Games
https://ac.nowcoder.com/acm/contest/30256/G
前i堆石子取出j堆异或和为sum,使得sum^sum=0,使得后手必胜。
每堆石子的数量最大为1000,极端情况会出现二进制10个1,最大为1023,k最大取1023.
#include <bits/stdc++.h>
#define long long ll
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=3e9+7;
int f[1001][11][1024],a[1001];
signed main()
{
int t;scanf("%d",&t);
while(t--)
{
memset(f,0,sizeof(f));
int n,d;scanf("%d%d",&n,&d);
int sum=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),sum^=a[i];
for(int i=0;i<=n;i++)
f[i][0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=d;j++)
for(int k=0;k<1024;k++){
f[i][j][k]=f[i-1][j-1][k^a[i]]+f[i-1][j][k];
f[i][j][k]%=mod;
}
}
int ans=0;
for(int j=0;j<=d;j++)
ans+=f[n][j][sum],ans%=mod;
cout<<ans%mod<<endl;
}
return 0;
}
A - Calandar
由于一年的天数和一个月的天数,取模于5都等于 0,所以只要考虑天数即可。若天数小于前面,则加上30取模5。根据周几加上天数,将5和0等价。
#include <bits/stdc++.h>
#define long long ll
using namespace std;
const int inf=0x3f3f3f3f;
string s[5]={"Friday","Monday","Tuesday","Wednesday","Thursday"};
signed main()
{
int t;scanf("%d",&t);
while(t--)
{
int y1,m1,d1,y2,m2,d2;string ss;
cin>>y1>>m1>>d1>>ss>>y1>>m2>>d2;
int tmp=(d2+30-d1)%5,ans;
if(ss=="Monday")
ans=(tmp+1)%5;
else if(ss=="Tuesday")
ans=(tmp+2)%5;
else if(ss=="Wednesday")
ans=(tmp+3)%5;
else if(ss=="Thursday")
ans=(tmp+4)%5;
else
ans=(tmp+5)%5;
cout<<s[ans]<<endl;
}
return 0;
}
H Dominoes
空格移动的方向要和将要移动的骨牌另一端的格子相一致
#include <bits/stdc++.h>
#define long long ll
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int dx[5]={1,0,-1,0};
int dy[5]={0,1,0,-1};
map<pair<int,int>,pair<int,int> >mp;
struct node
{
int x,y;
}cur;
bool vis[12][maxn];
signed main()
{
int n,m,k;
while(cin>>n>>m>>k){
mp.clear();memset(vis,0,sizeof(vis));
for(int i=1;i<=k;i++)
{
int a,b,c,d;cin>>a>>b>>c>>d;
mp[{a,b}]={c,d};mp[{c,d}]={a,b};
vis[a][b]=1;vis[c][d]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!vis[i][j])
{
cur.x=i;cur.y=j;break;
}
memset(vis,0,sizeof(vis));
int ans=0;
//cout<<cur.x<<" "<<cur.y<<endl;
queue<node>q;q.push(cur);
while(!q.empty())
{
cur=q.front();q.pop();
int xx=cur.x,yy=cur.y;
if(vis[xx][yy])
continue;
vis[xx][yy]=1;
for(int i=0;i<4;i++)
{
int x1=xx+dx[i],y1=yy+dy[i];
int x2=mp[{x1,y1}].first,y2=mp[{x1,y1}].second;
if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&abs(x2-x1)==abs(dx[i])&&abs(y2-y1)==abs(dy[i])&&!vis[x2][y2])
{
q.push(node{x2,y2});
ans++;
}
}
}
cout<<ans<<endl;
}
return 0;
}
F - Stones in the Bucket
思维题,虽然比较简单,但是思路挺清晰的
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int a[maxn];
signed main()
{
int t;cin>>t;
while(t--)
{
int n;cin>>n;
int sum=0;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]),sum+=a[i];
int tmp=sum/n,s1=0,s2=0;
for(int i=1;i<=n;i++)
{
if(a[i]<tmp)
s1+=tmp-a[i];
else if(a[i]>tmp)
s2+=a[i]-tmp;
}
cout<<s1+(s2-s1)<<endl;
}
return 0;
}
H - Tokens on the Segments
对于我的难点在于优先队列和结构体结合的排序上,没用过几次,掌握的不好。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
struct node
{
int x,y;
bool operator <(const node &a)const
{
if(a.x==x)
return a.y<y;
return a.x<x;
}
}e[maxn];
signed main()
{
int t;cin>>t;
while(t--)
{
priority_queue<node>q;
int n;cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&e[i].x,&e[i].y);
q.push(e[i]);
}
int mx=0,ans=0;
while(!q.empty())
{
node cur=q.top();q.pop();
if(cur.x>mx)
{
ans++;
mx=cur.x;
}
else if(cur.x<=mx&&cur.x+1<=cur.y)
{
cur.x++;
q.push(cur);
}
}
cout<<ans<<endl;
}
return 0;
}