题目已经保证s比t小了,那么只需要将s增加1(看成26进制数),然后比较是否相等即可。我居然跪了2发。
#include <bits/stdc++.h>
using namespace std;
char s[110];
char t[110];
int main(){
scanf("%s",s);
scanf("%s",t);
int len=strlen(s);
s[len-1]++;
int i=len;
while(i--){
if(s[i]>'z'){
s[i]='a';
s[i-1]++;
}else{
break;
}
}
if(i==-1||strcmp(s,t)==0){
printf("No such string");
}else{
printf("%s",s);
}
return 0;
}
统计每个字母有几个,扫两遍,第一遍满足完全一样的,第二遍满足大小写不符的。
#include <bits/stdc++.h>
using namespace std;
const int maxn=200010;
char s[maxn];
char t[maxn];
int cnt[200];
int main(){
scanf("%s",s);
scanf("%s",t);
int lens=strlen(s);
int lent=strlen(t);
for(int i=0;i<lent;i++){
cnt[t[i]]++;
}
int ans1=0;
int ans2=0;
for(int i=0;i<lens;i++){
if(cnt[s[i]]){
cnt[s[i]]--;
ans1++;
s[i]=0;
}
}
for(int i=0;i<lens;i++){
if(s[i]){
if(s[i]<'a'){
if(cnt[s[i]+32]){
cnt[s[i]+32]--;
ans2++;
}
}else{
if(cnt[s[i]-32]){
cnt[s[i]-32]--;
ans2++;
}
}
}
}
cout<<ans1<<" "<<ans2<<endl;
return 0;
}
直接模拟即可,记录第几个位置是第几个应用和第几个应用在第几个位置。
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
int a[maxn];
int _a[maxn];
int main(){
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
_a[a[i]]=i;
}
long long ans=0;
for(int i=1;i<=m;i++){
int b;
scanf("%d",&b);
int t=_a[b];
ans+=((_a[b]-1)/k+1);
if(t>1){
swap(_a[b],_a[a[t-1]]);
swap(a[t],a[t-1]);
}
}
cout<<ans<<endl;
return 0;
}
特别水的概率dp。dp(i,j)表示第i秒里面有j人。每个状态由两种状态转移而来,上一秒进来人和没有进来人。
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
double dp[2010][2010];
int main(){
int n,t;
double p;
cin>>n>>p>>t;
dp[0][0]=1.0;
for(int i=1;i<=t;i++){
for(int j=0;j<=n;j++){
if(j)dp[i][j]+=dp[i-1][j-1]*p;
if(j!=n) dp[i][j]+=dp[i-1][j]*(1.0-p);
else dp[i][j]+=dp[i-1][j];
}
}
double ans=0.0;
for(int i=1;i<=n;i++){
ans+=dp[t][i]*i;
}
printf("%.8lf\n",ans);
return 0;
}
第一眼看上去像差分约束,其实就是贪心。很容易推出只要保证所有ai<ai+k即可。把这些数分为1~k组,每一组是独立的,一组一组处理连续的'?',方法是贪心使得所有问号的绝对值之和尽量小(优先让连续'?'中最中间的等于0,如果不行就按制约条件修改值)。具体见代码。
#include <bits/stdc++.h>
using namespace std;
int a[100010];
const int INF=1e9+1e5+7;
int get_first(int MIN,int MAX,int len){
int re=max(-(len-1)/2,MIN); //优先让最中间为0,受最左边制约
re=min(re,MAX-len+1); //受最右边制约
return re;
}
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
char tmp[16];
scanf("%s",tmp);
if(tmp[0]=='?'){
a[i]=INF; //把问号暂时置为INF
}else{
a[i]=atoi(tmp);
}
}
for(int i=1;i<=k;i++){
int s=i+k;
int t=0;
if(a[i]==INF){
a[i]=-INF;
if(i+k>n)a[i]=0;
s=i;
t=i;
}
int j=i+k;
while(j<=n){
if(a[j]==INF){ //问号
a[j]=a[j-k]+1;
t=j;
if(j+k>n){
int tmp=get_first(a[s],INF,(t-s)/k+1);
for(int l=s;l<=t;l+=k){
a[l]=tmp++;
}
}
}else{ //碰到了数字,处理之前的那一串?
int tmp=get_first(a[s],a[j]-1,(t-s)/k+1);
for(int l=s;l<=t;l+=k){
a[l]=tmp++;
}
s=j+k;
}
j+=k;
}
}
bool ok=1;
for(int i=1;i<=k;i++){
int j=i+k;
while(j<=n){
if(a[j]<=a[j-k]){
ok=0;
break;
}
j+=k;
}
}
if(ok){
for(int i=1;i<=n;i++){
printf("%d ",a[i]);
}
printf("\n");
}else{
printf("Incorrect sequence\n");
}
return 0;
}
本文详细解析了Codeforces Round #293 Division 2的比赛题目,包括字符串比较、字母统计、智能手机应用模拟、概率DP和贪心策略解题。A题关注字符串大小比较,B题涉及字母频率统计,C题需要模拟应用安装顺序,D题通过动态规划解决扶梯问题,E题用贪心算法处理连续问号的约束问题。
6726

被折叠的 条评论
为什么被折叠?



