2023 CCPC Henan Provincial Collegiate Programming Contest
2023 CCPC Henan Provincial Collegiate Programming Contest
思路:暴力枚举
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>PII; typedef pair<string,int>PSI; const int N=2e5+5,INF=0x3f3f3f3f,Mod=998244353; const double eps=1e-6; typedef long long ll; //#define int long long int T; string s; int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>T; while(T--){ cin>>s; if(s.size()==1)cout<<"NaN\n"; else{ bool ok=false; vector<int>a(26,0); for(int i=0;i<s.size();++i){ int b=s[i]-'a'; if(a[b]==0){ bool ok1=true; int m=(i+s.size())/2; for(int j=i+1,p=s.size()-1;j<=m;++j,--p){ if(s[j]!=s[p]){ ok1=false;break; } } if(ok1)ok=true; } else break; if(ok)break; a[b]++; } if(ok)cout<<"HE\n"; else cout<<"NaN\n"; } } return 0; }
思路:求出前缀最大值和后缀最小值,对于每个k,分段点的前缀最大值不能大于后缀最小值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>PII; typedef pair<string,int>PSI; const int N=1e6+5,INF=0x3f3f3f3f,Mod=998244353; const double eps=1e-6; typedef long long ll; //#define int long long int T; int n,a[N],ma[N],mi[N]; int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n; for(int i=1;i<=n;++i){ cin>>a[i]; ma[i]=max(a[i],ma[i-1]); } mi[n]=a[n]; for(int i=n-1;i>=1;--i){ mi[i]=min(a[i],mi[i+1]); } int res=1; for(int i=1;i<n;++i){ bool ok=true; for(int j=i+1;j<=n;j+=i){ if(ma[j-1]>mi[j]){ ok=false;break; } } if(ok)res++; } cout<<res; return 0; }
思路:dp,f(i,j,k)表示走到(i,j)已经用了k个'?'后走过的'1'的个数;
1.s[i][j] 为'0':f(i,j,k)=max(f(i-1,j,k),f(i,j-1,k))
2.s[i][j] 为'1':f(i,j,k)=max(f(i-1,j,k),f(i,j-1),k)+1
3.s[i][j] 为'?':更改为'1'为:f(i,j,k)=max(f(i-1,j,k-1),f(i,j-1,k-1))+1
不更改:f(i,j,k)=max(f(i-1,j,k),f(i,j-1,k))
考虑到转移过程中无意义的状态,可以转换为二维为f(j,k),要避免原始状态被更新,k从大到小遍历,那么
1.s[i][j] 为'0':f(j,k)=max(f(j,k),f(j-1,k))
2.s[i][j] 为'1':f(j,k)=max(f(j,k),f(j-1),k)+1
3.s[i][j] 为'?':更改为'1'为:f(j,k)=max(f(j,k-1),f(j-1,k-1))+1
不更改:f(j,k)=max(f(j,k),f(j-1,k))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>PII; typedef pair<string,int>PSI; const int N=5e2+5,INF=0x3f3f3f3f,Mod=998244353; const double eps=1e-6; typedef long long ll; //#define int long long int T; int n,m,x; string s[N]; int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>T; while(T--){ cin>>n>>m>>x; for(int i=1;i<=n;++i){ string ss; cin>>ss; s[i]=' '+ss; } vector<vector<int>>f(m+1,vector<int>(x+1,0)); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ for(int k=x;k>=0;--k){ if(s[i][j]!='?'){ f[j][k]=max(f[j][k],f[j-1][k]); if(s[i][j]=='1')f[j][k]++; } else{ f[j][k]=max(f[j][k],f[j-1][k]); if(k!=0){ f[j][k]=max(f[j][k],max(f[j][k-1],f[j-1][k-1])+1); } } } } } cout<<f[m][x]<<'\n'; } return 0; }
思路:将序列a排序,求出相邻两个数的差值b,枚举所有长度为k-1的区间,min为最小的差值bi,max为差值的区间和,统计最小的min*max
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>PII; typedef pair<string,int>PSI; const int N=2e5+5,INF=0x3f3f3f3f,Mod=998244353; const double eps=1e-6; #define int long long int T; int n,kk; int a[500005]; int s[500005]; int d1[500006][20]; int lg[500006]; int ma[500006]; void stb(){ lg[0]=-1 , lg[1]=0; for(int i=2;i<n;i++) lg[i]=lg[i>>1]+1; for(int j=1;j<=20;j++) { for(int i=1;i+(1<<j)-1<n;i++) { d1[i][j]=min(d1[i][j-1],d1[i+(1<<(j-1))][j-1]); } } } int max1(int l,int r){ int k=lg[r-l+1]; return max(d1[l][k],d1[r-(1<<k)+1][k]); } int min1(int l,int r){ int k=lg[r-l+1]; return min(d1[l][k],d1[r-(1<<k)+1][k]); } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n>>kk; for (int i = 1; i <=n ; ++i) { cin>>a[i]; } sort(a+1,a+1+n); for (int i = 1; i <n ; ++i) { s[i]=a[i+1]-a[i]; } for (int i = 1; i <n ; ++i) { ma[i]=ma[i-1]+s[i]; } for (int i = 1; i <n ; ++i) { d1[i][0]=s[i]; } stb(); int ans=1e18; kk--; for (int i = 1; i <n ; ++i) { if(i+kk-1<n){ ans=min((ma[i+kk-1]-ma[i-1])*min1(i,i+kk-1),ans); } } cout<<ans<<'\n'; }
思路:数据可用__int128或double存
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; #define ll unsigned long long #define endl '\n' const int N=1e5+10; map<int,vector<string>> mp; map<int,vector<string>> mmp; map<int,vector<string>> fh; queue<int> q; stack<int> st; void print(__int128 num) { if(num>9) print(num/10); putchar(num%10+'0'); } ll change(){ ll ans=0; while(q.size()){ ans=ans*10+q.front();q.pop(); } return ans; } ll ksm(ll a,ll b){ __int128 res=1; if(a>1000000000&&b>=2)return (ll)0; if(a==1)return (ll)1; while(b){ res*=a; b--; //print(res);cout<<"\n"; if(res>(__int128)(1e18)){ return (ll)0; } } return (ll)res; } string change2(ll z){ while(z){ st.push(z%10); z/=10; } string tt=""; while(st.size()){ tt+=(char)('0'+st.top());st.pop(); } return tt; } int main(){ ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); mp[0]={".......", ".......", "0000000", "0.....0", "0.....0", "0.....0", "0.....0", "0.....0", "0000000", "......."}; mp[1]={".......", ".......", "......1", "......1", "......1", "......1", "......1", "......1", "......1", "......."}; mp[2]={".......", ".......", "2222222", "......2", "......2", "2222222", "2......", "2......", "2222222", "......."}; mp[3]={".......", ".......", "3333333", "......3", "......3", "3333333", "......3", "......3", "3333333", "......."}; mp[4]={".......", ".......", "4.....4", "4.....4", "4.....4", "4444444", "......4", "......4", "......4", "......."}; mp[5]={".......", ".......", "5555555", "5......", "5......", "5555555", "......5", "......5", "5555555", "......."}; mp[6]={".......", ".......", "6666666", "6......", "6......", "6666666", "6.....6", "6.....6", "6666666", "......."}; mp[7]={".......", ".......", "7777777", "......7", "......7", "......7", "......7", "......7", "......7", "......."}; mp[8]={".......", ".......", "8888888", "8.....8", "8.....8", "8888888", "8.....8", "8.....8", "8888888", "......."}; mp[9]={".......", ".......", "9999999", "9.....9", "9.....9", "9999999", "......9", "......9", "9999999", "......."}; mmp[0]={".....", "00000", "0...0", "0...0", "0...0", "00000", ".....", ".....", ".....", "....."}; mmp[1]={".....", "....1", "....1", "....1", "....1", "....1", ".....", ".....", ".....", "....."}; mmp[2]={".....", "22222", "....2", "22222", "2....", "22222", ".....", ".....", ".....", "....."}; mmp[3]={".....", "33333", "....3", "33333", "....3", "33333", ".....", ".....", ".....", "....."}; mmp[4]={".....", "4...4", "4...4", "44444", "....4", "....4", ".....", ".....", ".....", "....."}; mmp[5]={".....", "55555", "5....", "55555", "....5", "55555", ".....", ".....", ".....", "....."}; mmp[6]={".....", "66666", "6....", "66666", "6...6", "66666", ".....", ".....", ".....", "....."}; mmp[7]={".....", "77777", "....7", "....7", "....7", "....7", ".....", ".....", ".....", "....."}; mmp[8]={".....", "88888", "8...8", "88888", "8...8", "88888", ".....", ".....", ".....", "....."}; mmp[9]={".....", "99999", "9...9", "99999", "....9", "99999", ".....", ".....", ".....", "....."}; fh[0]={".......", ".......", ".......", ".......", "=======", ".......", "=======", ".......", ".......", "......."}; fh[1]={".......", ".......", "IIIIIII", "...I...", "...I...", "...I...", "...I...", "...I...", "IIIIIII", "......."}; fh[2]={".......", ".......", "N.....N", "NN....N", "N.N...N", "N..N..N", "N...N.N", "N....NN", "N.....N", "......."}; fh[3]={".......", ".......", "FFFFFFF", "F......", "F......", "FFFFFFF", "F......", "F......", "F......", "......."}; int t;cin>>t; string s,tt,aa,bb; ll a,b; ll z; while(t--){ cin>>s; for(int i=0;i<s.size();i++){ if(s[i]=='^'){ a=change(); } else if(s[i]=='}'){ b=change(); } else if(s[i]>='0'&&s[i]<='9')q.push(s[i]-'0'); } aa=change2(a);bb=change2(b); z=ksm(a,b); //cout<<a<<' '<<b<<' '<<z<<'\n'; if(z){ tt=change2(z); for(int i=0;i<10;i++){ cout<<"."; for(int j=0;j<aa.size();j++){ cout<<mp[aa[j]-'0'][i]<<"."; } for(int j=0;j<bb.size();j++){ cout<<mmp[bb[j]-'0'][i]<<"."; } cout<<fh[0][i]<<"."; for(int j=0;j<tt.size();j++){ cout<<mp[tt[j]-'0'][i]<<"."; } cout<<endl; } }else{ for(int i=0;i<10;i++){ cout<<"."; for(int j=0;j<aa.size();j++){ cout<<mp[aa[j]-'0'][i]<<"."; } for(int j=0;j<bb.size();j++){ cout<<mmp[bb[j]-'0'][i]<<"."; } cout<<fh[0][i]<<"."; cout<<fh[1][i]<<"."; cout<<fh[2][i]<<"."; cout<<fh[3][i]<<"."; cout<<endl; } } cout<<endl; } return 0; }
思路:max:每个数分配0.5,剩余的分给一个数
min:求可以分出的最大整数s,使得每个数可以分到小于0.5的数,那么s<0.5*k,min为n-s
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>PII; typedef pair<string,int>PSI; const int N=2e5+5,INF=0x3f3f3f3f,Mod=998244353; const double eps=1e-6; typedef long long ll; #define int long long int T; int n,k; int R(double x){ int y=(int)x; x-=y; if(x>=0.5)y++; return y; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>T; while(T--) { cin>>n>>k; int a=0.5*k,b; if(a==0.5*k)b=a-1; else b=a; b=min(n,b); cout<<n-b<<' '; double c=1.0*n/0.5; if(c<=k){ cout<<max(n,(int)c)<<'\n'; } else{ double y=1.0*n-(k-1)*0.5; int s=R(y); cout<<k-1+s<<'\n'; } } return 0; }
思路:将n个数按奇数从小到大排后,偶数接着从大到小排,(n>=10)可以看出删去n-1和2后一定正确,那么将2放到5和7中间,n-1放到n-6和n-4中间一定正确,特判一下n为11时,将n-1放到3和5后即可;n<10的情况枚举所有排列即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>PII; typedef pair<string,int>PSI; const int N=1e5+5,INF=0x3f3f3f3f,Mod=998244353; const double eps=1e-6; typedef long long ll; //#define int long long int T,n; int primes[N],idx; bool st[N]; void init(){ st[1]=true; for(int i=2;i<=N-5;++i){ if(!st[i])primes[idx++]=i; for(int j=0;primes[j]*i<=N-5;++j){ st[primes[j]*i]=true; if(i%primes[j]==0)break; } } } int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n; init(); if(n<=8){ vector<int>ve(n); for(int i=0;i<n;++i)ve[i]=i+1; bool ok=false; while(next_permutation(ve.begin(),ve.end())){ bool ok1=true; for(int i=0;i<n;++i){ int j=i+1; if(i==n-1)j=0; if(st[abs(ve[i]-ve[j])]){ ok1=false;break; } } if(ok1){ ok=ok1; break; } } if(ok)for(auto v:ve)cout<<v<<' '; else cout<<-1; } else{ vector<int>ans; int p; if(n%2)p=n-6; else p=n-4; if(n==11)p=3; for(int i=1;i<=n;i+=2){ if(i==n-1)continue; ans.push_back(i); if(i==5)ans.push_back(2); if(i==p)ans.push_back(n-1); } for(int i=n;i>1;i-=2){ if(i%2)i--; if(i==n-1||i==2)continue; ans.push_back(i); if(i==p)ans.push_back(n-1); } for(auto v:ans)cout<<v<<' '; } return 0; }