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

浙公网安备 33010602011771号