练习记录-atcoder-abc292(A-E)
E是补的 考试的时候写的垃圾dfs 有地方错了 没过
A 小写转换大写

#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; int gcd(int x,int y){int k=0; if(x<y){k=x;x=y;y=k;}while(x%y!=0){k=x%y;x=y;y=k;}return y;} ll _power(ll a,int b){ll ans=1,res=a;while(b){if(b&1) ans=ans*res%mod;res=res*res%mod;b>>=1;}return ans%mod;} void solve(){ string s; cin>>s; for(int i=0;i<s.length();i++){ if(s[i]<='z'&&s[i]>='a'){ char ch=s[i]-32; cout<<ch; } else cout<<s[i]; } } int main(){ solve(); }
B 计算黄牌红牌个数 输出是否罚下场 拿个数组记录就行 黄牌++,红牌直接+2,大于2就下场

#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; int f[MAXN]; int gcd(int x,int y){int k=0; if(x<y){k=x;x=y;y=k;}while(x%y!=0){k=x%y;x=y;y=k;}return y;} ll _power(ll a,int b){ll ans=1,res=a;while(b){if(b&1) ans=ans*res%mod;res=res*res%mod;b>>=1;}return ans%mod;} void solve(){ int n,m;cin>>n>>m; for(int i=0;i<m;i++){ int o,p;cin>>o>>p; if(o==3){ if(f[p]>=2) cout<<"Yes\n"; else cout<<"No\n"; } else if(o==2){ f[p]=2; } else f[p]++; } } int main(){ solve(); }
C 寻找正整数ABCD的可能组合数量 使AB+CD=N
想了很久 决定暴力,先预处理出对于一个数(1-200000) 乘法分解的可能数量
(如果分解到乘方方法数就+1,否则方法数+2)
最后遍历(1-n) 对每两组数的方法数相乘求和即可

#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; ll f[MAXN]; int gcd(int x,int y){int k=0; if(x<y){k=x;x=y;y=k;}while(x%y!=0){k=x%y;x=y;y=k;}return y;} ll _power(ll a,int b){ll ans=1,res=a;while(b){if(b&1) ans=ans*res%mod;res=res*res%mod;b>>=1;}return ans%mod;} void solve(){ int n;cin>>n; for(int i=1;i<=200000;i++){ for(int j=1;j<=sqrt(i);j++){ if(i%j==0){ f[i]++; if(j*j!=i) f[i]++; } } } ll ans=0; for(int i=1;i<n;i++){ ans+=f[i]*f[n-i]; } cout<<ans; } int main(){ close; solve(); }
D 题意求对每个连通区块,是否满足点数==变数
使用并查集处理一遍
1遍历每一个边,记录每个区块的边数
2遍历每个点 记录每个区块的点数
3遍历每个点 检查边数点数是否相等

#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; int f[MAXN],n,m,sum[MAXN],k[MAXN]; struct node{ int u,v; }N[MAXN]; void clean(){ for(int i=1;i<=n;i++) f[i]=i; } int find(int x){ if(x!=f[x]) f[x]=find(f[x]); return f[x]; } void add(int x,int y){ int fx=find(x),fy=find(y); if(fx!=fy) f[fx]=fy; } void solve(){ cin>>n>>m; clean(); for(int i=1;i<=m;i++){ cin>>N[i].u>>N[i].v; add(N[i].u,N[i].v); } for(int i=1;i<=m;i++){ f[N[i].u]=find(N[i].u); sum[f[N[i].u]]++; } //int maxs=0,maxt=0; int flag=1; for(int i=1;i<=n;i++){ k[f[i]]++; //if(f[i]!=sz[i].size()) flag=0; } for(int i=1;i<=n;i++){ // k[f[i]]++; if(sum[i]!=k[i]) flag=0; } if(flag) cout<<"Yes\n"; else cout<<"No\n"; } int main(){ solve(); }
E 寻找对于每个点能到达的长度>=2的点的个数
原来使用n^2遍历+dfs检查长度 很复杂 如果有大佬debug感谢orz

#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; #define int long long int f[2005]; vector<int> adj[2005]; int dfs(int u,int v,int val){ int flag=0; for(auto it:adj[u]){ if(f[it]) continue; if(it==v&&val) return 1; else { f[it]=1; flag=max(flag,dfs(it,v,1)); f[it]=0; } } return flag; } void solve(){ int n,m;cin>>n>>m; for(int i=0;i<m;i++){ int u,v; cin>>u>>v; adj[u].push_back(v); } int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(j==i) continue; f[i]=1; if(dfs(i,j,0)) ans++; f[i]=0; } } cout<<ans; } signed main(){ solve(); }
看了官方题解,直接记录所有的点能到达的点的数量,最后减去边的数量(其实就是长度为1的对数) 就是正确答案 用bfs来寻找连通数量

#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod =1e9+7; const ll inf =0x3f3f3f3f; const ll INF =0x3f3f3f3f3f3f3f3f; vector<int> adj[2005]; int f[2005]; int gcd(int x,int y){int k=0; if(x<y){k=x;x=y;y=k;}while(x%y!=0){k=x%y;x=y;y=k;}return y;} ll _power(ll a,int b){ll ans=1,res=a;while(b){if(b&1) ans=ans*res%mod;res=res*res%mod;b>>=1;}return ans%mod;} void solve(){ int n,m; cin>>n>>m; for(int i=0;i<m;i++){ int u,v; cin>>u>>v; adj[u].push_back(v); } int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) f[j]=0; f[i]=1; queue<int> sz; sz.push(i); while(sz.size()){ int x=sz.front(); sz.pop(); for(auto it:adj[x]){ if(f[it]) continue; sz.push(it); ans++; f[it]=1; } } } ans-=m; cout<<ans; } int main(){ solve(); }
F好像是数学题 后续有补将继续更新