Codeforces Round #530 (Div. 2)C. Postcard

一道模拟题。
题意:
给你一段字符串,然后里面有俩中特殊符号‘ ? ’和’ * ‘ ,’ ? '可以删除或者留下前面的字符,‘ * ’可以删除,留下或者重复(很多次)前面的字符。
思路:
我们可以先删除特殊字符以及特殊字符前面一个字符(此处判断k与剩下字符的个数,如果他比全删除之后的字符个数还小那就不可能或者当“*”数量为0时又大于他所有没删除字符的个数也不可能),然后判断需不需要加上,如果遇到’ * ‘就直接加满他所需要的字符个数,后面就不需要再加了,然后开始漫长的模拟之路。
代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
char s[200+10];
char a[200+10]; 
int main(){
	scanf("%s",s);
	int k;
	cin>>k;
	int  sum=strlen(s);
	int sum2=0,sum1=0;
	for(int i=0;i<strlen(s);i++){
		if(s[i]=='*') sum1++;
		if(s[i]=='?') sum2++;
	}
	if(k<sum-2*sum2-2*sum1) puts("Impossible");
	else if(!sum1&&(k<sum-2*sum2||k>sum>sum2)) puts("Impossible");
	else {
		int ans=k-(sum-2*sum1-2*sum2);
//		printf("sum=%d sum1=%d sum2=%d ans=%d\n",sum,sum1,sum2,ans);
		int pos=0;
		for(int i=0;i<sum;i++){
			if(pos==k) break;
			if(s[i+1]=='?'&&ans>=1) {
				a[pos]=s[i];
				pos++;
				i++;
				ans--;
			}  
			else if(s[i+1]=='*'&&ans>=1){
					for(int j=1;j<=ans;j++){
						a[pos]=s[i];
						pos++;
					}
					ans=0;
					i++;
			}
			else {
				if(s[i]=='?'||s[i]=='*') continue;
				while(s[i+1]=='?'||s[i+1]=='*') i+=2; 
				a[pos]=s[i];
//					printf("%c\n",a[pos]);
				pos++;
			
			}
		}
//		printf("pos=%d\n",pos);
		if(pos==k) printf("%s\n",a);
		else puts("Impossible");
	}
} 

后来又看了其他简单的方法,代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    int k;
    cin>>s>>k;
    string ans="";
    for(int i=0;i<s.length();i++){
        if(s[i]=='*' ||  s[i]=='?')
        	ans.pop_back();
        else ans+=s[i];
    }
    int cnt=0;
    for(int i=0;i<s.length();i++){
        if(ans.length()>=k) break;
        if(s[i]=='?') {
         	ans.insert(i-cnt-1,string(1,s[i-1]));//string s(n,c) //生成一个字符串,包含n个c字符
          	cnt++;
        }
        if(s[i]=='*'){ 
         	ans.insert(i-cnt-1,string(k-ans.length(),s[i-1]));
          	cnt++;
        }    
    }
    if(ans.length()==k)
     	cout<<ans<<endl;
    else
     	cout<<"Impossible"<<endl;
}

你可能感兴趣的:(codeforce)