以后比完赛就要趁早来写解题报告……等得久了之后一旦下一场没打好,写这一场的时候就也没心情了……
这一场是打得较好的一场,Rank达到了1694,离DIv1最近的一次……
但是#266 掉到1593了,因为精神状态太差……
废话不多说先来写一些265的解题报告
这个题目是给你一个反着写的二进制数,问你加一之后有多少个数位变化了,题意不是很容易理解,但是理解了之后就简单的很呢Code:
#include <cmath>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
bool cmp(const int a, const int b)
{
return a > b;
}
int val[101],ans[101];
int main()
{
int n;
string s;
cin>>n>>s;
memset(val,0,sizeof val);
memset(ans,0,sizeof ans);
for(int i=0;i<n;i++)
val[i]=s[i]-'0';
int flag=0;
for(int pos=0;pos<n;pos++)
{
if(val[pos]==0 && flag==0)
{
ans[pos]=1;
flag=1;
}
else if(val[pos]==1 && flag==0)
{
ans[pos]=0;
flag=0;
}
else ans[pos]=val[pos];
}
int cnt=0;
for(int i=0;i<n;i++)
{
if(ans[i]!=val[i])cnt++;
//cout<<ans[i]<<":"<<val[i]<<endl;
}
cout<<cnt<<endl;
return 0;
}
想想我平时看邮件的习惯(强迫症自信最优解):点进第一封没读过的邮件,然后看看下一封读过没,读过了的话点出来再点进之后的第一封没读过的,要是没读过的话直接点击下一封去读。
于是就可以直接边读入边操作了,嘛当时保险点还是中规中矩的写的每一个分四种情况(00、01、10、11,0-没读过,1-读过了)
Code:
#include <cmath>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
bool cmp(const int a, const int b)
{
return a > b;
}
int sta[1024];
int dp[1024];
int main()
{
int n;cin>>n;
memset(sta,0,sizeof sta);
memset(dp,0,sizeof dp);
for(int i=1;i<=n;i++)
{
scanf("%d",&sta[i]);
if(sta[i]==1 && sta[i-1]==1) dp[i]=dp[i-1]+1;
else if(sta[i]==1 && sta[i-1]==0) dp[i]=dp[i-1]+1;
else if(sta[i]==0 && sta[i-1]==1) dp[i]=dp[i-1]+1;
else if(sta[i]==0 && sta[i-1]==0) dp[i]=dp[i-1];
if(sta[n]==0 && dp[n]!=0)dp[n]--;
//cout<<dp[i]<<" ";
}
cout<<dp[n]<<endl;
return 0;
}
说是有一个长度为n的字符串,字符只能在字母表的前p个选取,当前字符串内一定不存在回文序列(一个字符的不算哦),问你它的下一个不存在回文的"能忍的"字符串是什么,如果没有输出NO。
这个就得讲讲咯,我们从末尾开始一次一次加一,遇到超过p限制了就变成a,前一位加一(n进制模拟嘛^_^),如果数字们都用完了就No了,这个其实很容易想到的哦,然后就是判定啦,咱们到底啥算能用啥算不能用呢?
嘿嘿就是这里啦~ 我们进一位的时候你以为当前位变成1嘛?不不不,我们直接就去遍历前一位不要这一位啦,这样的话是不是只要【当前判定位】的前2位和前1位和自己不一样那么它前面都一定不回文呀?
那么,我找到了之后怎么回头确定后头的字符以保证不回文还得最小呢?
请看:012012012012012012012012..... 如果当前位和前一位有0或者1了咋办呢? ^_^你说呢?
砍掉一个向后找呗120120120120...\201201201201201201... ^_^
那么就over咯~
Code:
#include <cmath>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
bool cmp(const int a, const int b)
{
return a > b;
}
int val[1024];
int main()
{
int n,p;cin>>n>>p;
string s;cin>>s;
if(n==1 && p==1){cout<<"NO"<<endl;return 0;}
memset(val,0,sizeof val);
for(int i=0;i<n;i++)
val[i]=s[i]-'a';
int pos=n-1;
val[pos]++;
while(1)
{
if(pos==0)
{
if(val[pos]>=p) {cout<<"NO"<<endl;return 0;}
else {break;}
}
else if(val[pos]>=p)
{
val[pos]=0;
pos--;
val[pos]++;
}
else
{
if((pos>1 && val[pos]==val[pos-2]) || val[pos]==val[pos-1])val[pos]++;
else {break;}
}
}
for(int i=pos+1;i<n;i++)
{
for(int j=0;j<p;j++)
{
if(i>0 && j==val[i-1])continue;
else if(i>1 && j==val[i-2])continue;
else {val[i]=j;break;}
}
}
for(int i=0;i<n;i++)
{
printf("%c",'a'+val[i]);
}
return 0;
}