CF510

CF510A

水题,找规律模拟即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define int ll
#define gc getchar
#define pc putchar
const int N=2e5+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int c,t,n,m;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    n=read();m=read();
    for(int i=1;i<=n;i++){
        if(i&1){
            for(int j=1;j<=m;j++)cout<<'#';cout<<endl;
        }else if(i%4){
            for(int j=1;j<=m-1;j++)cout<<'.';cout<<'#'<<endl;
        }else{
            cout<<'#';for(int j=2;j<=m;j++)cout<<'.';cout<<endl;
        }
    }
    return 0;
}

CF510B

简单bfs。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define int ll
#define gc getchar
#define pc putchar
const int N=1e2+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,a[N][N],vis[N][N];
char c;
int dx[5]={0,-1,0,0,1};
int dy[5]={0,0,-1,1,0};
inl bool check(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m;}
inl bool bfs(int x,int y){
    queue<pair<int,int>>q;
    q.push({x,y});vis[x][y]=1;
    while(!q.empty()){
        int nx=q.front().first,ny=q.front().second;q.pop();
        for(int i=1;i<=4;i++){
            int xx=nx+dx[i],yy=ny+dy[i];
            if(!check(xx,yy))continue;
            if(a[xx][yy]^a[x][y])continue;
            if(vis[xx][yy]){
                if(vis[xx][yy]+1==vis[nx][ny])continue;
                return 1;
                
            }
            vis[xx][yy]=vis[nx][ny]+1;
            q.push({xx,yy});
        }
    }
    return 0;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>c;
            a[i][j]=c-'A'+1;
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(!vis[i][j])ans|=bfs(i,j);
        }
    }
    puts(ans?"Yes":"No");
    return 0;
}

CF510C

比较时我们对于两个子串中第一个出现不同的字母,第一个向第二个连边,表示第一个字母字典序比第二个小
那么显然就是在求这个不联通图的拓扑序 显然有环则无解

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define int ll
#define gc getchar
#define pc putchar
const int N=1e2+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,in[N];
int head[N],to[N],nxt[N],cnt;
inl void add(int u,int v){
    nxt[++cnt]=head[u];
    to[cnt]=v;
    head[u]=cnt;
}
string s,t;
queue<int>q;
vector<int>v;
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    cin>>s;s+='a'-1;
    for(int i=1;i<=n-1;i++){
        cin>>t;t+='a'-1;
        for(int i=0;i<min(s.size(),t.size());i++){
            if(s[i]==t[i])continue;
            if(s[i]=='a'-1)continue;
            add(s[i]-'a'+1,t[i]-'a'+1);in[t[i]-'a'+1]++;
            break;
        }
        s=t;
    }
    for(int i=1;i<=26;i++){
        if(in[i])continue;
        q.push(i);v.push_back(i);
    }
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i];
            if(!--in[y])
                q.push(y),v.push_back(y);
        }
    }
    if(in[0]){puts("Impossible");return 0;}
    if(v.size()^26)puts("Impossible");
    else for(auto i:v)cout<<(char)(i+'a'-1);
    return 0;
}

CF510D

首先分析题面:无限长的序列显然做不了。
我们发现如果能选出的卡片能使人从0移到1,那么就一定可以到达任何位置。
每个卡片使用次数不定,设为 \(x_1,x_2...x_k\)(正代表右移,负代表左移)
那么 \(x_1l_1+x_2l_2+...+x_nl_n=1\)
\(l\) 为已知量 \(x\) 为未知量
那么这是一个不定方程 容易想到裴蜀定理
\(ax+by=1\) 要求 \(gcd(a,b)|1\) 凭直觉猜出方程要求 \(gcd(l_1,l_2...l_k)=1\)
那么问题转化为选出价值和最少的卡片 满足 \(l\) 的最大公因数为1
由于 \(l\le 10^9\) 每个数最多不超过9个质因数 考虑状压:
\(f[i][s]\) 表示第 \(i\) 个数 质因子状态为 \(s\) (第 \(k\) 个质因子是否被消去)的最小花费
\(n^2\) 转移:对于数 \(l_j\) 根据其中是否含有 \(l_i\) 的质因子求出状态 \(ss\)
\(f[i][s\text{&}ss]=min(f[i][s]+c[j])\)

CF510E

首先 判两个数和是否是质数可以 \(O(n^2)\)
考虑怎么判无解:发现 \(a_i\ge 2\) 那么满足条件的两个数一奇一偶
那么可以把奇偶数分开 合为质数连边 那么其实是个二分图 dinic跑一下
因为左右一共两个点 连到原点/汇点容量为2 其他边为1
这样因为满足条件的奇偶数一定为 \(\cfrac{n}{2}\) 那么最大流为 \(n\) 有解
对于方案 在残余网络上找流过的边dfs即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define int ll
#define gc getchar
#define pc putchar
const int N=2e5+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,e,dis[N],vis[N],now[N],s,t,a[N];
int head[N],nxt[N],to[N],w[N],cnt=1;
int maxflow;
inl void add(int u,int v,int c){
    nxt[++cnt]=head[u];to[cnt]=v;w[cnt]=c;head[u]=cnt;
    nxt[++cnt]=head[v];to[cnt]=u;w[cnt]=0;head[v]=cnt;
}
inl bool bfs(){
    memset(vis,0,sizeof vis);
    memset(dis,0x3f,sizeof dis);
    memcpy(now,head,sizeof now);
    queue<int>q;
    q.push(s);dis[s]=0;
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=nxt[i]){
            int y=to[i],c=w[i];
            if(c&&dis[y]>dis[x]+1){
                dis[y]=dis[x]+1;
                if(!vis[y]){q.push(y);vis[y]=1;}
            }
        }
    }
    return dis[t]<=n+m+2;
}
inl int dfs(int x,int flow){
    if(x==t)return flow;
    int rlow,used=0;
    for(int i=now[x];i;i=now[x]=nxt[i]){
        int y=to[i],c=w[i];
        if(c&&dis[y]==dis[x]+1){
            if(rlow=dfs(y,min(c,flow-used))){
                w[i]-=rlow;
                w[i^1]+=rlow;
                used+=rlow;
                if(used==flow)break;
            }
        }
    }
    return used;
}
inl bool isprime(int x){
    for(int i=2;i*i<=x;i++){
        if(x%i)continue;
        return 0;
    }
    return 1;
}
vector<vector<int>>v;
vector<int>k;
inl void dfs2(int x){
    vis[x]=1;k.push_back(x);
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i],c=w[i];
        if(vis[y])continue;
        if(y==s||y==t)continue;
        if(a[x]&1&&c)continue;
        if(!(a[x]&1)&&!c)continue;
        dfs2(y);
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    n=read();
    s=n+1,t=n+2;
    for(int i=1;i<=n;i++){
        a[i]=read();
        if(a[i]&1)add(s,i,2);
        else add(i,t,2);
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(!isprime(a[i]+a[j]))continue;
            if(a[i]&1)add(i,j,1);
            else add(j,i,1);
        }
    }
    while(bfs())maxflow+=dfs(s,inf);
    if(maxflow^n){puts("Impossible");return 0;}
    memset(vis,0,sizeof vis);
    for(int i=1;i<=n;i++){
        if(vis[i])continue;
        dfs2(i);
        v.push_back(k);
        k.clear();
    }
    cout<<v.size()<<endl;
    for(auto i:v){
        cout<<i.size()<<' ';
        for(auto j:i){
            cout<<j<<' ';
        }
        cout<<endl;
    }
    return 0;
}
posted @ 2023-11-29 14:57  xiang_xiang  阅读(41)  评论(0)    收藏  举报