几道cf水题

时间:2021-05-27 04:13:17

题意:给你包含n个元素的数组和k种元素,要求k种元素要用完,并且每种颜色至少用一次,n个元素,如果某几个元素的值相同,这些个元素也不能染成同一种元素。

思路:如果元素个数n小于k或者值相同的元素的个数大于k,那么一定无解,输出-1。用一个num[a[i]]记录每种相同值的元素出现次数,若大于k,无解。这道题的关键在于如何处理值相同的这些元素,可以用一个二维数组f[i][j]来表示状态,其中i表示对应元素值,j代表颜色。只要对于相同的i,j值不同就可以了。每个元素用什么颜色记录在一个数组ans[i]中,最后输出ans[i]就可以了。

Array K-Coloring 

#include<iostream>
#include<cstdio>
#include<string.h>
#define maxn 5005
using namespace std;
int n,k,flag=;
int cnt=;
int a[maxn];
int ans[maxn];
int num[maxn]={};
int vis[maxn][maxn];
int main()
{
cin>>n>>k;
memset(vis,,sizeof(vis));
for(int i=;i<n;i++)
{
cin>>a[i];
num[a[i]]++;
if(num[a[i]]>k)
flag=;
}
if(n<k||flag)
cout<<"NO";
else
{
cout<<"YES"<<endl;
for(int i=;i<n;i++)
{
if(cnt<=k)
{
ans[i]=cnt;
vis[cnt][a[i]]=;
cnt++;
}
else
{
for(int j=;j<=k;j++)
{
if(!vis[j][a[i]])
{
ans[i]=j;
vis[j][a[i]]=;
break;
}
}
}
}
for(int i=;i<n;i++)
printf("%d ",ans[i]);
}
return ;
}

题意:这里有n个门,它们的初始耐劳度为a[i]。你每次能对门造成x的破坏,修理工能每次使门回复y的牢固度。你和修理工都采用最优策略,请问10的100次轮后你能破坏掉多少门。

思路:你的最优策略是每次先打掉牢固度低于你破坏力的门,修理工的最优策略是每次先修牢固度低于你破坏力的门。那么如果x>y的话,这种情况下最坏的情形是x-y仅仅相差1,每扇门牢固度都是10^5,共有100扇门,这样100*10^5也远远比10^100小,则最后你一定能破坏所有门。相反若x<=y,你只能破坏掉最初牢固度小于你破坏力的门cnt,数量为(cnt+1)/2.当这些门破坏后,剩下的门你破坏哪个,修理工就修理哪一个,最后也破坏不了一扇门

#include<iostream>
#include<stdio.h> using namespace std; int cnt=;
int n,x,y;
int a[]; int main()
{
cin>>n>>x>>y;
for(int i=;i<=n;i++)
{
cin>>a[i];
if(a[i]<=x)
cnt++;
}
if(x>y)
cout<<n;
if(x<=y)
cout<<(cnt+)/;
return ;
}