CF一些杂题

Codeforces Round #789 B. Tokitsukaze and Meeting

显然可以拆成横竖两部分来看
竖的的好算 我们模拟一下 发现每次相当于整体右移 然后再向第一列加一个数 我们直接维护一个m长的col即可
行有点复杂
我们可以设dp[i]为第i个数进来时的行有多少个 我们显然可以从dp[i-m]也就是下一行的同一位置转移过来
要是我们当前与上一个1的距离小于m 那我们就证明 这一行有一个1 所以直接dp[i]=dp[i-m]+1 else dp[i]=dp[i-m]

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
int up(int a,int b){return a<0?a/b:(a+b-1)/b;}
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

void solve() {
     int n,m;cin>>n>>m;
     string s;cin>>s;
     vector<int>ans(n*m),row(n*m),col(n*m);
     int last=-1;
     for(int i=0;i<n*m;i++){
         if(s[i]=='1')last=i;
         if(i<m){
             if(~last)row[i]=1;
         }else{
             if(i-last<m)row[i]=row[i-m]+1;
             else row[i]=row[i-m];
         }
         ans[i]+=row[i];
     }
     int t=0;
     for(int i=0;i<n*m;i++){
         if(s[i]=='1'&&!col[i%m]){
             t++;
             col[i%m]=1;
         }
         ans[i]+=t;
     }
     for(int i=0;i<n*m;i++)cout<<ans[i]<<' ';cout<<endl;
}
signed main(){
    fast
    int t;t=1;cin>>t;
    while(t--) {
        solve();
    }
    return ~~(0^_^0);
}

Codeforces Round #825 D. Equal Binary Subsequences

显然可以拆成两个两个一组 要是不是偶数成对 显然-1
其他要是一对是相同 一个分给a 一个分给b 显然合理
如果不同 显然只有01 10两种结构 我们一个拿0下一个拿1这样rorate一遍即可

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
int up(int a,int b){return a<0?a/b:(a+b-1)/b;}
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

void solve() {
    int n;cin>>n;
    n*=2;
    string s;cin>>s;
    s=')'+s;
    int cnt0=0,cnt1=0;
    for(int i=1;i<=n;i++){
        if(s[i]=='0')cnt0++;
        else cnt1++;
    }
    if(cnt1%2||cnt0%2){cout<<-1<<endl;return;}
    vector<int>op;
    for(int i=1;i<=n;i+=2){
        if(s[i]!=s[i+1]){
            if(op.empty()){
                op.push_back(i);
            }else{
                if(s[op.back()]=='0'){
                    s[i]=='1'?op.push_back(i):op.push_back(i+1);
                }else{
                    s[i]=='0'?op.push_back(i):op.push_back(i+1);
                }
            }
        }
    }
    cout<<op.size()<<' ';for(auto i:op)cout<<i<<' ';cout<<endl;
    for(int i=1;i<=n;i+=2)cout<<i<<' ';cout<<endl;
}
signed main(){
    fast
    int t;t=1;cin>>t;
    while(t--) {
        solve();
    }
    return ~~(0^_^0);
}

Dytechlab Cup 2022 C. Ela and Crickets

显然我们到达每一个块 只有一种情况
而且我们发现我们可以平移两个单位是不改变结果的
但是有一种特殊情况就是 三个紧贴角落 显然是只能一条线走的 特判即可
else 我们就直接%2判断是不是空格

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
int up(int a,int b){return a<0?a/b:(a+b-1)/b;}
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
pair<int,int>p[4];
void solve() {
    int n;cin>>n;
    set<pair<int,int>>s;
    for(int i=1;i<=3;i++){
        int x,y;cin>>x>>y;
        s.insert({x,y});
        p[i].first=x,p[i].second=y;
    }
    int x,y;cin>>x>>y;
    if(s.count({1,1})&&s.count({2,1})&&s.count({1,2})){
           if(x==1||y==1)YES
           else NO
        return;
    }
    if(s.count({n,n})&&s.count({n,n-1})&&s.count({n-1,n})){
        if(x==n||y==n)YES
        else NO
        return;
    }
    if(s.count({1,n})&&s.count({1,n-1})&&s.count({2,n})){
        if(x==1||y==n)YES
        else NO
        return;
    }
    if(s.count({n,1})&&s.count({n,2})&&s.count({n-1,1})){
        if(x==n||y==1)YES
        else NO
        return;
    }
    s.clear();
    for(int i=1;i<=3;i++){
        auto [x,y]=p[i];
        s.insert({x%2,y%2});
    }
    if(s.count({x%2,y%2}))YES
    else NO
}
signed main(){
    fast
    int t;t=1;cin>>t;
    while(t--) {
        solve();
    }
    return ~~(0^_^0);
}

Codeforces Round #826 G. Kirill and Company

n范围1e4 显然我们可以对于每一个点做一遍暴力
看他能到的status是多少 这里就需要一层一层的做
因为普通的bfs没有考虑到距离要是相等的情况 我们还需要更新一次dp
注意的是 我们这里更新dp时要是已经是1了 就要continue 不然会同层内形成环
处理完之后我们直接暴力的跑一遍背包即可

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int M = 998244353;
const int mod = 998244353;
//#define int long long
int up(int a,int b){return a<0?a/b:(a+b-1)/b;}
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int n, m, f, k;
vector<int>g[N];
int h[N], p[N], dp[N][1<< 6], vis[N];
int bit_cnt(int x) {
    int cnt = 0;
    while (x) x-=x&-x,cnt++;
    return cnt;
}
void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)g[i].clear(), h[i] = 0, p[i] = 0, vis[i] = 0;
    for (int i = 1; i <= n; i++)memset(dp[i], 0, sizeof(dp[i]));
    for (int i = 1; i <= m; i++) {
        int u, v; cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    cin >> f;
    for (int i = 1; i <= f; i++)cin >> h[i];
    cin >> k;
    for (int i = 1; i <= k; i++)cin >> p[i];
    vector<pair<int,int>>q;q.push_back({1,0});
    while(q.size()){
        vector<pair<int,int>>nxt;
        for(auto i:q)vis[i.first]=1;
        for(auto i:q){
            auto [u,status]=i;
            for(auto v:g[u]){
                int ns=status;
                for(int j=1;j<=k;j++)
                    if(v==h[p[j]]){
                        ns|=1<<j-1;
                    }
                if(!vis[v]&&!dp[v][ns]){
                    nxt.push_back({v,ns});
                    dp[v][ns]=1;
                }
            }
        }
        q=nxt;
    }
    for(int i=1;i<=k;i++)h[p[i]]=0;
    vector<int>pre(1<<k),now(1<<k);
    int ans=0;
    pre[0]=1;
    for (int i = 1; i <= f; i++) {
        if (h[i] == 0)continue;
        int u = h[i];
        for (int x = 0; x < 1<<k; x++)
            for (int y = 0; y < 1<<k; y++)
                if (dp[u][y]&&pre[x]) {
                    now[x|y] = 1;
                    ans=max(ans,bit_cnt(x|y));
                }
        pre=now;
    }
    cout<<k-ans<<endl;
}
signed main(){
    fast
    int t;t=1;cin>>t;
    while(t--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-10-12 14:20  ycllz  阅读(25)  评论(0)    收藏  举报