CodeForces 1267

题目:B–Balls of Buma
题意

给你一个字符串(代表不同颜色),让你插入一个字符(一种颜色)后,可以消掉整个字符串。(相同颜色、长度变长、长度>=3才会抵消)

思路

将原串变成“种类串”(例如:AABBAA—> ABA)后,“种类串”应当是回文串,且长度应该是奇数。
同时,一个可以被消去的串,根据中心对称的同类部分的长度和,应当>=3。中心部分长度应当>=2.满足以上条件,答案为中心部分答案+1;

代码
#include<iostream>
#include<string>
#include<map>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131 
#define INF 0x3f3f3f3f
#define P pair<int,int>
#define ls p<<1
#define rs p<<1|1
//#define int long long
//#define int long long
//const ll lnf=0x3f3f3f3f3f3f3f3f;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-5;
const double pai=acos(-1.0);
const int N=3e5+10;
const int maxn=110;
const int mod=1000000007;
//const int d[4][2]={0,1,1,0,-1,0,0,-1};
//int day[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};
char s[N],p[N];
int t[N];
bool check(int x)
{
	int l=0,r=x-1;
	while(l<r)
	{
		if(p[l]==p[r]&&t[l]+t[r]>=3) l++,r--;
		else return 0;
	}
	return 1;
}
int main()
{
        scanf("%s",s);
        int len=strlen(s),cnt=0,ans=0;
        p[cnt++]=s[0];
        t[cnt-1]++;
        for(int i=1;i<len;i++)
        {
         	if(s[i]!=s[i-1]) p[cnt++]=s[i],t[cnt-1]++;
        	else t[cnt-1]++;
	}
        if(cnt==1)
	{
		if(len>=2) printf("%d\n",len+1);
		else printf("0\n");
		return 0;
	}
	if(cnt%2==0||!check(cnt))
	{
		printf("0\n");
		return 0;
	}
	int tot=1;
	for(int i=1;i<len;i++)
	{
		if(s[i]!=s[i-1]) tot++;
		if(tot==(cnt/2+1)) ans++;
		if(tot>(cnt/2+1)) break;
	}
	if(ans>=2) printf("%d\n",ans+1);
	else printf("0\n");
	return 0;
}
题目:E–Elections
题意

n个候选人,m个投票站,每个人在每个投票站都有自己的得票,n号候选人是坏的,你的目的是阻止坏人胜出(即不让他的总得票数比其他所有人都要高),你可以取消一些投票站的结果(就是让所有人在这个投票站都不得票),求最少取消的投票站数目及其编号。

思路

枚举每个人,求每个人每个投票站和n号坏人得票的差值,对差值排序,从大到小累加,>=0的站台留着,<0的消去,最后得到这个人的最少取消的站台数,最后从每个人的最少取消的站台数中去最小值即为答案。(还是看代码吧/(ㄒoㄒ)/~~)

代码
#include<iostream>
#include<string>
#include<map>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131 
#define INF 0x3f3f3f3f
#define P pair<int,int>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-5;
const double pai=acos(-1.0);
const int N=1e6+10;
const int maxn=110;
const int mod=1000000007;
vector<int>ans;
vector<int>tep;
int a[110][110];
struct node
{
	int v;
	int p;
}st[110];
bool cmp(node x,node y)
{
	return x.v>y.v;
}
int main()
{
        int n,m,minn=INF;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
    	        for(int j=1;j<=n;j++)
         	{
    	     	      scanf("%d",&a[i][j]);
	        }
        }
	for(int i=1;i<n;i++)
	{
		tep.clear();
		for(int j=1;j<=m;j++)
		{
			st[j].v=a[j][i]-a[j][n];
			st[j].p=j;
		}
		sort(st+1,st+m+1,cmp);
		int sum=0;
		for(int j=1;j<=m;j++)
		{
			if(sum+st[j].v>=0) sum+=st[j].v;
			else tep.push_back(st[j].p);
		}
		if(tep.size()<minn)
		{
			ans=tep;
			minn=tep.size();
		}
	}
	printf("%d\n",minn);
	for(int i=0;i<minn;i++)
	printf("%d ",ans[i]);
	return 0;
}
题目:J–Just Arrange the Icons
题意

n个软件,每个软件都有种类,相同的可以放在一个屏幕上,而屏幕有容量 s (自己决定),你要么在这个屏幕放 s-1 个 ,要么放 s 个,让你求最小的屏幕数。

思路

枚举 s ,确定最少屏幕数。
一种软件需要的屏幕数 =(这种软件的总数 - 1)/ s +1;同时还要满足( 需要的屏幕数 * (s−1) <=这种软件的数目 <=需要的屏幕数 * s) 。

代码
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131 
#define INF 0x3f3f3f3f
#define P pair<int,int>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-5;
const double pai=acos(-1.0);
const int N=2e6+10;
const int maxn=110;
const int mod=1000000007;
int a[N];
int main()
{
        int t;
        scanf("%d",&t);
        while(t--)
        {
        	memset(a,0,sizeof(a));
        	vector<int>v;
        	int n;
         	scanf("%d",&n);
         	for(int i=1;i<=n;i++)
         	{
    		        int x; 
    		        scanf("%d",&x);
    		        if(!a[x]) v.push_back(x);
    		        a[x]++;
		}
		int cnt=n/v.size()+1;
		int ans=INF;
		for(int i=2;i<=cnt;i++)
		{
			bool flag=0;
			int sum=0;
			for(int j=0;j<v.size();j++)
			{
				int tot=(a[v[j]]-1)/i+1;
				if(a[v[j]]<tot*(i-1)||a[v[j]]>tot*i)
				{
					flag=1;
					break;
				}
				sum+=tot;
			}
			if(flag==1) continue;
			else ans=min(ans,sum);
		}
		printf("%d\n",ans);
	}
	return 0;
}
题目:L–Lexicography
题意

给你给一个 n * l 的串,让你构造 n 个长 l 的单词,单词按字典序排序,要求第 k 个单词的字典序尽可能的小。

思路

对串按字典序排序,先构造前 1-k 个单词,先按序赋予 k 个单词首字母,看有没有和 k 相同首字母的单词,如果有,从最前面的相同首字母的单词开始赋予第二个字母,一直重复到没有跟 k 相同的单词或 k 长度达到 l ;如果没有,直接将 k 赋到长度 l ,剩下的单词按剩下的串赋值。(语文不大好,还是看代码吧/(ㄒoㄒ)/~~)

代码
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131 
#define INF 0x3f3f3f3f
#define P pair<int,int>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-5;
const double pai=acos(-1.0);
const int N=1e6+10;
const int maxn=110;
const int mod=1000000007;
string ans[1010],s;
int n,l,k,len,pre;
int main()
{
        scanf("%d%d%d",&n,&l,&k);
        cin>>s;
        sort(s.begin(),s.end());
        if(k==1)
        {
    	        for(int i=1;i<=l;i++) ans[k]+=s[len++];
	}
	else
	{
		for(int i=1;i<=k;i++) ans[i]+=s[len++];
		for(int i=1;i<=k;i++)
		{
			if(ans[i][0]==ans[k][0]) 
			{
				pre=i;
				break;
			}
		}
	}
	while(ans[k].size()<l)
	{
		if(pre==k)
		{
			for(int i=ans[k].size();i<l;i++) ans[k]+=s[len++];
		}
		else
		{
			for(int i=pre;i<=k;i++) ans[i]+=s[len++];
			int ll=ans[k].size();
			for(int i=pre;i<=k;i++)
			{
				if(ans[i][ll-1]==ans[k][ll-1]) 
				{
					pre=i;
					break;
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(ans[i].size()<l)
		{
			while(ans[i].size()<l) for(int j=ans[i].size();j<l;j++) ans[i]+=s[len++];
		}
	}
	for(int i=1;i<=n;i++)
	{
		cout<<ans[i]<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值