求调 NOIp T2
  • 板块题目总版
  • 楼主王熙文
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/11/24 19:54
  • 上次更新2023/11/24 22:55:29
查看原帖
求调 NOIp T2
353688
王熙文楼主2023/11/24 19:54

如题,考场写的 60,民间数据也都是 60,只有官方数据下挂成了 50。

拼的部分分,n<=10,m<=10 是暴力枚举,TFU 是记录每个数最后一次被赋值,剩下的是一个乱搞:将初值全 T 的序列操作一次,再用上一次的终值操作,这样操作 5 次。再将所有初值和终值不相同的位置设为 U,再次操作,直到不存在这样的位置。

感觉这个乱搞在 U+ 的情况下的对的。

#include<bits/stdc++.h>
using namespace std;
int n,m;
char op[100010];
int x[100010],y[100010];
int now[100010],lst[100010];
int llst[100010];
void upd()
{
    for(int i=1; i<=m; ++i)
    {
        if(op[i]=='+') now[x[i]]=now[y[i]];
        else if(op[i]=='-') now[x[i]]=2-now[y[i]];
        else now[x[i]]=(op[i]=='T'?0:op[i]=='U'?1:2);
    }
}
int ans;
void dfs(int wz)
{
    if(wz==n+1)
    {
        for(int i=1; i<=n; ++i) lst[i]=now[i];
        upd();
        bool flag=1; int cnt=0;
        for(int i=1; i<=n; ++i) flag&=(lst[i]==now[i]),cnt+=(lst[i]==1);
        if(flag) ans=min(ans,cnt);
        for(int i=1; i<=n; ++i) now[i]=lst[i];
        return;
    }
    now[wz]=0,dfs(wz+1),now[wz]=1,dfs(wz+1),now[wz]=2,dfs(wz+1);
}
int main()
{
    ios::sync_with_stdio(false),cin.tie(0);
    int testid,t; cin>>testid>>t; while(t--)
    {
        cin>>n>>m;
        bool flag=1;
        for(int i=1; i<=n; ++i) llst[i]=0;
        for(int i=1; i<=m; ++i)
        {
            cin>>op[i];
            if(op[i]=='+' || op[i]=='-') cin>>x[i]>>y[i],flag=0;
            else cin>>x[i],llst[x[i]]=(op[i]=='T'?0:op[i]=='U'?1:2);
        }
        if(n<=10 && m<=10)
        {
            ans=1e9,dfs(1);
            cout<<ans<<'\n';
            continue;
        }
        else if(flag)
        {
            int cnt=0;
            for(int i=1; i<=n; ++i) cnt+=(llst[i]==1);
            cout<<cnt<<'\n';
            continue;
        }
        for(int i=1; i<=n; ++i) now[i]=0;
        upd();
		upd();
		upd();
		upd(); 
        for(int i=1; i<=n; ++i) lst[i]=now[i];
        upd();
        while(1)
        {
            bool flag=1;
            for(int i=1; i<=n; ++i)
            {
                if(now[i]!=lst[i]) now[i]=1,flag=0;
            }
            if(flag) break;
            for(int i=1; i<=n; ++i) lst[i]=now[i];
            upd();
        }
        int cnt=0;
        for(int i=1; i<=n; ++i) cnt+=(now[i]==1);
        cout<<cnt<<'\n';
    }
    return 0;
}
2023/11/24 19:54
加载中...