Codeforces Round #638 (Div. 2) BC

B
要构造一个循环节为k的字符串
计算相异元素个数c,
若c>k,不可能构造
若c<=k,取c个不同元素,再用相同元素补足k个,
由于不限制插入个数,把每个数都延长为一个循环,即输出n个循环

#include
using namespace std;

const int MAX_N=105;
int a[MAX_N],cnt[MAX_N],v[MAX_N];
vector<int> tab;
 
int main()
{
	int t; cin>>t;
	while(t--){
		memset(cnt,0,sizeof(cnt));
		memset(v,0,sizeof(v));
		tab.clear();
		
		int n,k; scanf("%d%d",&n,&k);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		
		int c=0; //mx=0
		for(int i=1;i<=n;i++){
			cnt[a[i]]++;
			//mx=max(mx,cnt[a[i]]);
			if(cnt[a[i]]==1) c++;	//相异元素个数 
		}
		
		if(c>k) { puts("-1"); continue; }
		
		int re=k-c;	//重复个数 
		for(int i=1;i<=n;i++){
			if(!v[a[i]]) v[a[i]]=1, tab.push_back(a[i]);
			else if(re) re--,tab.push_back(a[i]);
		}
		
		
		
		
		printf("%d\n",(int)tab.size()*n);
		
		for(int i=1;i<=n;i++){
			for(int j=0;j<tab.size();j++) printf("%d ",tab[j]);
		}
		puts("");
	
	}
	
	
	return 0;
} 

C
先排序,
1~k依次分配,答案一定选第k个字母开头
若s[k]!=s[1],只输出一个字母,因为剩下所有字母加到第1个字母后面,不会影响第k个

若s[k]==s[1],
若剩下的有不同元素,输出k后面全部(使大字母尽量后,
(删中间会使后面大字母前移,删后面不能保证第k小
若剩下元素全部相同,按个数平均分配(字典序相同,使长度尽量短)

#include
using namespace std;

const int MAX_N=1E5+5;
char s[MAX_N]; 

int main()
{
	int t; cin>>t;
	while(t--){
		int n,k; scanf("%d%d%s",&n,&k,s+1);
		
		sort(s+1,s+1+n);//
		
		if(s[k]!=s[1]) { printf("%c\n",s[k]); continue; }	
		

		int flag=0;
		for(int i=k+1;i<=n-1;i++) if(s[i]!=s[i+1]) { flag=1; break; } 			
		if(flag) printf("%s\n",s+k);		
		else {									
			for(int i=k;i<=n;i+=k) printf("%c",s[i]);
			if(n%k) printf("%c",s[n]);
			puts("");
		} 
		
		
		
		
	} 
	
	
	
	
	
	return 0;
} 

你可能感兴趣的:(Codeforces Round #638 (Div. 2) BC)