23暑假友谊赛
23暑假友谊赛
马猴烧酒
思路:枚举对行的所有可能操作,判断列需要的操作次数是否满足条件;
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e4+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; string s[25]; void solve(){ int n,m,a,b;cin>>n>>m>>a>>b; for(int i=0;i<n;++i){ cin>>s[i]; } for(int i=0;i<(1<<n);++i){ int cnt=__builtin_popcount(i); if(cnt>a)continue; set<int>se; for(int j=0;j<n;++j){ if(!(i&(1<<j))){ for(int k=0;k<m;++k){ if(s[j][k]=='*')se.insert(k); } } } if(se.size()<=b){ cout<<"yes\n";return; } } cout<<"no\n"; return ; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //init(); cin>>T; while(T--){ solve(); } return 0; }
阶乘
思路:要求n!是p的倍数,说明n!的因子包含p的全部因子。
统计出p的所有因子,及其个数,那么p=a1k1*a1k2*...*amkm;
由于ai都是互质的,需要!n中的每种质因子是相互不影响的;
单独求出包含每种质因子全部个数的最小n,对所有n取最大即可;
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e6+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; int prime[N],cnt[N],idx,p; bool check(int x){ for(int i=1;i<=idx;++i){ int s=0,n=x; while(n){ s+=n/prime[i]; n/=prime[i]; } if(s<cnt[i])return false; } return true; } void solve(){ cin>>p; idx=0; for(int i=2;i<=p/i;++i){ if(p%i==0){ prime[++idx]=i; while(p%i==0){ cnt[idx]++; p/=i; } } } if(p>1)prime[++idx]=p,cnt[idx]++; int l=1,r=1e9,ans; while(l<=r){ int mid=l+r>>1; if(check(mid))r=mid-1,ans=mid; else l=mid+1; } cout<<ans<<'\n'; memset(prime,0,sizeof prime); memset(cnt,0,sizeof cnt); } signed main(){ //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //init(); cin>>t; while(t--){ solve(); } return 0; }
完全图
思路:求所有边的贡献,对于一条边,过这条边的链的数目为:以这条边两端点为根节点的子节点数(包括自己)的乘积。
将所有边的次数排序,次数越大的权值越小
#include<bits/stdc++.h> using namespace std; //#define int long long #define int __int128 typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; int read() { int res=0; char scan[1005]; scanf("%s",scan); for(int i=0;i<strlen(scan);i++) res*=10,res+=scan[i]-'0'; return res; } int n,m,mm; bool check(int k){ int b=n-k+1; int y=b*(b-1)/2; int le=mm-y; return le<=m; } void solve(){ n=read(),m=read(); mm=n*(n-1)/2; int l=1,r=n,ans; while(l<=r){ int mid=l+r>>1; if(check(mid))ans=mid,l=mid+1; else r=mid-1; } cout<<(long long)ans<<'\n'; return ; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //init(); T=read(); while(T--){ solve(); } return 0; }
A+B问题
思路:a和b的范围为 l~r,l= -2147483648 ,r=2147483647,且a+b=c;
定a1=l,b1=c-a1
定a2=r,b2=c-a2
答案为b1-b2+1=a2-a1+1
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e4+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; //string s[25]; void solve(){ /*int n,m,a,b;cin>>n>>m>>a>>b; for(int i=0;i<n;++i){ cin>>s[i]; }*/ int n;cin>>n; int a1=-2147483648,a2=2147483647; int b1=n-a1,b2=n-a2; cout<<b1-b2+1; } //-2147483648 ~ 2147483647 signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //init(); //cin>>T; while(T--){ solve(); } return 0; }
树上求和
思路:求所有边的贡献,对于一条边,过这条边的链的数目为:以这条边两端点为根节点的子节点数(包括自己)的乘积。
将所有边的次数排序,次数越大的权值越小
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; int h[N],ne[2*N],e[2*N],idx; int cnt[N]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int fa){ cnt[u]=1; for(int i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa)continue; dfs(j,u); cnt[u]+=cnt[j]; } } void solve(){ int n;cin>>n; memset(h,-1,sizeof h); for(int i=1,u,v;i<n;++i){ cin>>u>>v; add(u,v); add(v,u); } dfs(1,0); vector<int>ve; for(int i=2;i<=n;++i){ ve.push_back(cnt[i]*(n-cnt[i])); } sort(ve.begin(),ve.end(),greater<int>()); int ans=0; for(int i=1;i<n;++i){ ans+=i*ve[i-1]; } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; //init(); //cin>>t; while(t--){ solve(); } return 0; }
奇怪的背包问题增加了
思路:230=2*229,229=2*228,...
可以搜索找到凑成230的所有数,找不到则impossible
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; int have[35]; int cost[35]; int a[N]; bool dfs(int u,int c){ if(u<0)return false; cost[u]=min(c,have[u]); if(have[u]>=c)return true; //if(u==0)return false; return dfs(u-1,(c-have[u])*2); } void solve(){ int m;cin>>m; memset(have,0,sizeof have); memset(cost,0,sizeof cost); for(int i=0;i<m;++i){ cin>>a[i]; have[a[i]]++; } bool ok=dfs(30,1); if(!ok){ cout<<"impossible\n"; }else{ for(int i=0;i<m;++i){ if(cost[a[i]]){ cout<<1;cost[a[i]]--; }else cout<<0; }cout<<'\n'; } return ; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //init(); cin>>T; while(T--){ solve(); } return 0; }
寻找子串
思路:暴力枚举每种子串
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e4+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; //string s[25]; void solve(){ /*int n,m,a,b;cin>>n>>m>>a>>b; for(int i=0;i<n;++i){ cin>>s[i]; }*/ string s;cin>>s; string ans="-1"; for(int i=1;i<=s.size();++i){ for(int j=0;j+i-1<s.size();++j){ string a=s.substr(j,i); if(ans=="-1"||a>ans)ans=a; } } cout<<ans; } //-2147483648 ~ 2147483647 signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //init(); //cin>>T; while(T--){ solve(); } return 0; }
最大的差
思路:排个序,首位就是相差最大的
#include<bits/stdc++.h> using namespace std; #define int long long typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=1e4+5,INF=0x3f3f3f3f,Mod=1e9+7; const double eps=1e-6; //string s[25]; void solve(){ /*int n,m,a,b;cin>>n>>m>>a>>b; for(int i=0;i<n;++i){ cin>>s[i]; }*/ int n;cin>>n; vector<int>a(n); for(int i=0;i<n;++i)cin>>a[i]; sort(a.begin(),a.end()); cout<<abs(a[n-1]-a[0]); } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; //init(); //cin>>T; while(T--){ solve(); } return 0; }