题意:
A:CodeForces 1216D:n个类型的剑被偷了,每个类型还剩a[1]……a[n]把剑。每个盗贼只能偷一个类型的剑且所有盗贼偷的剑数相同,求多少的贼和每个贼偷几把剑。
B:CodeForces 1216A:让一个字符串的所有偶数前缀中的a,b的数量相同。
C:CodeForces 1216B:给定n个罐子,第i个罐子a[i]需要射击 (a[i]x+1) 次,问击倒n个罐子最少需要射击多少次,并输出罐子的初始编号,x是在射击这个罐子之前已经射击了几个,第一个射击时 x=0。
D:CodeForces 1216C:给你一个白色矩形、两个黑色矩形的左下角和右上角的坐标,问你这两个黑色矩形是否把白色矩形全部覆盖。
E:CodeForces 1221A:一堆2的幂次数,问能不能合并成2048。
F:CodeForces 1221C:3个组分组,其中前两个组每个最少要有一个人在一个队里,求最多组数。
G:CodeForces 1221B: 输入n,构造一个nn的矩阵,矩阵只包含两种字母 ’ B’ ,‘W’ 。如果B在蓝色位置,W在红色位置时,B和W将打架,问打架次数最多的情况应该怎样放。
H:CodeForces 1221D:你有一个长度为n的序列,每次你可以令ai的值加1,但需要消耗bi的代价。现在,你希望花费尽可能少的代价修改你的序列,使序列中任意相邻两项不相等。
题解:
A:思路:排序找到最大值,计算剩下n个类型的剑的数量与最大值差值的最大公因数,记为每个盗贼偷的剑的数量,与最大值的差值除以被偷的剑数即为人数。
代码:
#include <bits/stdc++.h>
using namespace std;
long long n,a[200010],y,z,maxi,sum,ans;
long long gcd(long long a,long long b){
if(b==0)
return a;
else
return gcd(b,a%b);
}
int main()
{
cin>>n;
maxi=-1;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
maxi=a[n];
for(int i=1;i<=n;i++){
if(i==1)
sum=maxi-a[1];
else
sum=gcd(sum,maxi-a[i]);
}
for(int i=1;i<=n;i++)
ans+=(maxi-a[i])/sum;
cout<<ans<<' '<<sum<<endl;
}
C:思路:贪心,从最大的开始射击,用一个数组来储存顺序。
代码:
#include <bits/stdc++.h>
using namespace std;
int n,p,ans,j,mini,maxi,i,a[1010],b[1010];
int main()
{
ans=0;
j=-1;
cin>>n;
for(i=0;i<n;i++)
cin>>a[i];
mini=a[n-1];
for (i=n-2;i>=0;i--)
{
if(a[i]<mini)
mini=a[i];
}
maxi=mini;
for (j=0;j<n;j++)
{
for(i=0;i<n;i++)
{
if(a[i]>=maxi)
{
maxi=a[i];
p=i;
}
}
ans+=(j*maxi+1);
a[p]=0;
b[j]=p;
maxi=mini;
}
cout<<ans<<endl;;
for (i=0;i<n;i++)
cout<<b[i]+1<<' ';
}
D:思路:暴力把历遍白色矩形的四条边上点的坐标判一下是否在两个黑色矩形的任一个之内,只要有一个点不在就没有全部覆盖。注意应该用double的坐标每+0.5判断一下,不然可能会漏点。
代码:
#include<iostream>
using namespace std;
int x1,x2,x3,x4,x5,x6,y1,y2,y3,y4,y5,y6,f;
bool judge1(double x,double y)
{
if((x>=x3&&x<=x4)&&(y>=y3&&y<=y4))
return true;
else
return false;
}
bool judge2(double x,double y)
{
if((x>=x5&&x<=x6)&&(y>=y5&&y<=y6))
return true;
else
return false;
}
int main()
{
cin>>x1>>y1>>x2>>y2;
cin>>x3>>y3>>x4>>y4;
cin>>x5>>y5>>x6>>y6;
f=0;
for(double i=x1; i<=x2; i+=0.5)
{
if((judge1(i,y1)||judge2(i,y1))&&(judge1(i,y2)||judge2(i,y2)));
else
{
f=1;
break;
}
}
for(double i=y1; i<=y2; i+=0.5)
{
if((judge1(x1,i)||judge2(x1,i))&&(judge1(x2,i)||judge2(x2,i)));
else
{
f=1;
break;
}
}
if(f==0)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
E:思路:用switch来储存指数,从0次开始往上加当前次数一半,通过判断11位是否有数来确定答案。
代码:
#include <bits/stdc++.h>
using namespace std;
int q,n,s[30],x;
int main()
{
cin>>q;
while(q--){
cin>>n;
memset(s,0,sizeof(s));
for(int i=0;i<n;i++){
cin>>x;
switch(x){
case 1:s[0]++;break;
case 2:s[1]++;break;
case 4:s[2]++;break;
case 8:s[3]++;break;
case 16:s[4]++;break;
case 32:s[5]++;break;
case 64:s[6]++;break;
case 128:s[7]++;break;
case 256:s[8]++;break;
case 512:s[9]++;break;
case 1024:s[10]++;break;
case 2048:s[11]++;break;
default:s[12]++;
}
}
for(int i=0;i<=12;i++){
if(s[11])
break;
x=s[i]/2;
s[i]-=x*2;
s[i+1]+=x;
}
if(s[11])
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
F:思路:比较出前两组的较少的人数,再和三组均分后的人数比较,最小的为答案。
代码:
#include <bits/stdc++.h>
using namespace std;
int q,c,m,x,sum,ans;
int main()
{
cin>>q;
while(q--){
cin>>c>>m>>x;
sum=min(c,m);
ans=(c+m+x)/3;
ans=min(ans,sum);
cout<<ans<<endl;
}
}
G:题意:奇数行奇数列放 B,偶数行偶数列放B,其余放W就是答案
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(i%2){
if(j%2)
cout<<"W";
else
cout<<"B";
}
else{
if(j%2)
cout<<"B";
else
cout<<"W";
}
}
cout<<endl;
}
}
感受:今天基本都是思维题,基本上多想想是能考虑出来的。D卡在第三个测试样例过不去,模拟了,没找到问题,看完题解又去模拟一遍。G题题目有点没看明白。