Codeforcesの最初の週
先週、コードフォースでDiv2のA、B、Cをブラッシングします。他のOJと比較して、コードフォースは質問を考えることに重点を置いており、基本的な文法とマスターSTLを備えている限り、データ構造とアルゴリズムにあまり注意を払っていません。一般に、回答コードの量は少なく、質問の法則が見つかる限り、アルゴリズムテンプレートは使用されません。
Codeforces Round#668(Div2)B
質問は、配列が与えられた場合、配列の合計が0であることを意味します。右側の負の数から配列の正の数を削除すると、コインは消費されません。左側の負の数で正の数を削除する必要がある場合は、コインを消費する必要があり、消費量が最も少ないコインが実装されます。配列内の各要素は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
ナンバーゲームをしているのは2人で、1人目はマークのない数字を奇数の位置にしかマークできず、2人目はマークのない数字を偶数の位置にしかマークできません。最後の残りが偶数の場合、2番目の人が勝ち、最後の残りが奇数の場合、最初の人が勝ちます。実際、最初の人が勝ちたい場合、彼は最後まで奇数を保存する必要があります(奇数がある場合)、2番目は同じです。ゲーム内の配列の長さが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");
}
}
}