Codeforces刷题第一周
最近一周都在codeforces上刷Div2的A,B,C。相比于其他OJ,codeforces上的更多是思维题,并不太注重考察数据结构和算法,只要会基本语法和掌握STL就行。一般答案代码量较少,用不到算法模板,只要能够找到题目的规律就行。
Codeforces Round #668(Div2) B
题目的意思是给定一个数组,该数组的和为0,数组中若正数由右边的负数消除不消费coin,若正数需要用左边的负数消除,则需要消费coin,消费最少的coin实现数组中每个元素是0,用模拟实现。
#include<stdio.h>
#include<vector>
#include<cmath>
using namespace std;
int main()
{
int t,n;
long long int x;
vector<long long int> num;
scanf("%d",&t);
while(t--)
{
num.clear();
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld",&x);
num.push_back(x);
}
long long int oppnum=0,negnum=0;//oppnum记录留下的正数和,negnum记录留下的负数和,这两个值都会更新
for(int i=0;i<num.size();i++)
{
if(num[i]>=0) oppnum+=num[i];//如果为正数,统计到oppnum中
else//如果为负数,则可能会更新,消除正数
{
if(oppnum)//如果左边有正数
{
if(oppnum>abs(num[i]))//如果左边的正数和大于当前负数,则负数被消除为0,正数和oppnum会更新
{
oppnum=num[i]+oppnum;
num[i]=0;
}
else//如果左边的正数和小于当前负数,则正数被消除为0,负数和negnum和当前数num[i]会更新
{
oppnum=0;
num[i]=num[i]+oppnum;
negnum=negnum+num[i];
}
}
else negnum=negnum+num[i];//如果左边没有正数,则更新negnum
}
}
printf("%lld\n",oppnum);
}
}
Codeforces Round #668(Div2) C
判断一个未知字符串(全部由’0’和’1’组成)能否满足每一个k长度的子串中’0’和’1’的个数是一样的。假设a[i]-a[i+k]满足’0’和’1’的个数是相等的,若a[i+1]-a[i+1+k]要满足这个条件,易得a[i+1+k]=a[i],那这个字符串是以k为周期的循环字符串。
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
string s;
int t,n,x,k;
scanf("%d",&t);
getchar();
while(t--)
{
scanf("%d%d",&n,&k);
getchar();
cin>>s;
bool judge=true;
int sum1=0,sum2=0;
for(int i=0;i<k;i++)
{
int tmp=-1;//tmp有两个标记作用,一是标记这个循环节中是否出现非''字符;二是若出现非'?'字符,标记是'0'还是'1';
for(int j=i;j<n;j+=k)
{
if(s[j]!='?')//为'0'或者'1'
{
if(tmp!=-1&&s[j]-'0'!=tmp)//如果找到第一个非'?'字符并且不相等,则一定不循环
{
judge=false;
break;
}
tmp=s[j]-'0';//此前没找到非'?'字符或者与当前非'?'值相等
}
}
if(tmp!=-1)//若此循环节已知(即至少出现一次非'?'值)
{
if(tmp==0) sum1++;
else sum2++;
}
}
if(sum1>k/2||sum2>k/2) judge=false;//若'1'或者'0'的数量超过一半,那一定不满足条件
if(judge) printf("YES\n");
else printf("NO\n");
}
}
Codeforces Round #671(Div 2) A
有两个人玩数字游戏,第一个人只能标记奇数位置上的未标记数字,第二个人只能标记偶数位置上的未标记数字。若最后一个剩下的是偶数,则第二个人赢;若最后一个剩下的是奇数,则第一个人赢。其实第一个人想赢,就必须把奇数留到最后(若有奇数),第二个同理。若游戏中数组长度是1,则两个人都不能标记,不用选就定胜负。若游戏中数组长度是偶数,则第一个人把握主动权(实质上只能标记n-1个数字),只要数组中有奇数,则能赢,否则不能赢;若为奇数,同理可推。
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
int t,n;
scanf("%d",&t);
string s;
while(t--)
{
int sum=0;
scanf("%d",&n);
getchar();
cin>>s;
if(s.length()==1)
{
int x=s[0]-'0';
if(x%2==0) printf("2\n");
else printf("1\n");
}
else if(s.length()%2==1)
{
for(int i=0;i<s.length();i=i+2)
{
int x=s[i]-'0';
if(x%2==1) sum++;
}
if(sum!=0) printf("1\n");
else printf("2\n");
}
else
{
for(int i=1;i<s.length();i=i+2)
{
int x=s[i]-'0';
if(x%2==0) sum++;
}
if(sum!=0) printf("2\n");
else printf("1\n");
}
}
}