比赛链接:https://codeforces.com/contest/1369
A.FashionabLee
判断边数是否为4的倍数
#include <iostream>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
if(n%4==0)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
B.AccurateLee
举个例子:
000011001110001001001111111
将这个字符串分为三部分:
0000[110011100010010]1111111
中间的一系列1100、111000、100、10;形如10的串可以合并为1100、0、0、0;进而合并为0;
即[110011100010010]变为0;
所以,这个字符串最终变为0000[0]1111111;
可以发现,如果中间的[10]可以变成0,如果有的话,没有结果就是原串。
#include <iostream>
#include<string>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--){
int n;
string s;
cin>>n>>s;
int p1=0,p2=0;
for(int i=0;i<n;i++){
if(s[i]=='0')p1++;
else break;
}
for(int i=n-1;i>=0;i--){
if(s[i]=='1')p2++;
else break;
}
string res="";
bool t=false;
if(p1+p2<n)t=true;
while(p1--)res+="0";
if(t)res+="0";
while(p2--)res+="1";
cout<<res<<endl;
}
return 0;
}
C.RationalLee
首先要知道,w为1的朋友,分到最大的数字;
将朋友按w排升序,数字按a排升序;
a从后往前,w从前往后,将数字给朋友,一人一个,这时每个朋友有了自己最大的数字,注意w==1的朋友,这时也有了自己最小数字;
然后,a从前往后,w后往前,将数字给朋友,每个人按w-1个发数字,发满就到下一个人,这样可以消耗小的数字;
最后,每个朋友有了自己最大的数字和最小的数字,计算结果即可。
#include<bits/stdc++.h>
using namespace std;
const int MAX_N=2e5+5;
typedef long long ll;
int n,k;
int a[MAX_N],h[MAX_N];
void solve(){
sort(a,a+n);
sort(h,h+k);
ll res=0;
for(int i=0;i<k;i++){
res+=a[n-i-1];
if(h[i]==1)res+=a[n-i-1];
}
int p=0;
for(int i=k-1;i>=0;i--){
if(h[i]==1)break;
res+=a[p];
p+=h[i]-1;
}
cout<<res<<endl;
}
int main()
{
int T;
cin>>T;
while(T--){
cin>>n>>k;
for(int i=0;i<n;i++)scanf("%d",a+i);
for(int i=0;i<k;i++)scanf("%d",h+i);
solve();
}
return 0;
}
D.TediousLee
打表找规律:
n从1到20,结果为4的倍数,所以结果除4再观察如下:
0 0 1 1 3 6 12 24 49 97 195 390 780 1560 3121 6241 12483 24966 49932 99864;
可以发现如下规律,6个为一组,在前一结果的基础上:*2、*2、*2、*2+1、*2-1、*2+1
所以预处理所有结果即可。
关于如何打表:
写一个dfs计算以v为根的树的结果;
对于v的度d可能是0、1、3;
对于d为0,结果为0;
对于d为1,结果为子树的结果;
对于d为3,两个情况,一是v不染色,结果是3颗子树的和;二是v染色,那么v的子节点也染色,再计算下面有多少染色就可以了。
打表代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N=2e6+5;
const int M=1e9+7;
int n;
int d[MAX_N];
int child[MAX_N][3];
void net(){
int t=n;
for(int i=0;i<t;i++){
if(d[i]==0){
child[i][0]=n++;
d[i]++;
}
else if(d[i]==1){
child[i][1]=n++;
child[i][2]=n++;
d[i]+=2;
}
}
}
int dfs(int v){
if(d[v]==0)return 0;
if(d[v]==1)return dfs(child[v][0]);
int res1=0;
for(int i=0;i<3;i++)res1+=dfs(child[v][i]);
int res2=4;
for(int i=0;i<3;i++){
for(int j=0;j<d[child[v][i]];j++){
res2+=dfs(child[child[v][i]][j]);
}
}
return max(res1,res2);
}
void get(){
int res=dfs(0);
cout<<res/4<<endl;
}
void da(){
n=1;
for(int i=1;i<=20;i++){
cout<<i<<":";
get();
net();
}
}
int main()
{
da();
return 0;
}
ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N=2e6+5;
const int M=1e9+7;
int res[MAX_N];
int main()
{
res[1]=res[2]=0;
res[3]=res[4]=1;res[5]=3;
for(int i=6;i<=2e6;i++){
res[i]=(ll)res[i-1]*2%M;
if((i-6)%6==3||(i-6)%6==5)res[i]=((ll)res[i]+1)%M;
else if((i-6)%6==4)res[i]=((ll)res[i]-1+M)%M;
}
int T;
cin>>T;
while(T--){
int n;
cin>>n;
cout<<(ll)res[n]*4%M<<endl;
}
return 0;
}