山东省赛补题

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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值