比赛题解 部分题目较难
阴阳链
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <bits/stdc++.h> #define maxn 100005 using namespace std; int dp[maxn]; int de[maxn]; int a[maxn]; int f[2][maxn]; int main() { int n; while(cin>>n) { for(int i=1;i<=n;i++) { cin>>a[i]; f[0][i]=i; f[1][i]=i; } int maxs=0,x,z=0; for(int i=1;i<=n;i++) { for(int j=i-1;j>=1;j--) { if(a[i]>a[j]&&dp[i]<=de[j]+1) { dp[i]=de[j]+1; f[0][i]=j; } if(a[i]<a[j]&&de[i]<=dp[j]+1) { de[i]=dp[j]+1; f[1][i]=j; } } if(dp[i]>maxs) { maxs=dp[i]; x=i; z=0; } if(de[i]>maxs) { maxs=de[i]; x=i; z=1; } // cout<<dp[i]<<" "<<de[i]<<' '<<i<<' '<<a[i]<<endl; } /* for(int i=0;i<2;i++) { for(int j=1;j<=n;j++) { cout<<f[i][j]<<' '; } cout<<endl; } cout<<x<<endl; */ while(1) { cout<<a[x]<<' '; if(f[z][x]==x) break; x=f[z][x]; z=!z; } cout<<endl; } }
手写堆
#include <iostream> #include <algorithm> #include <cstring> #include <string> #include <cstdlib> #include <ctime> #include <fstream> struct aaa{int l,r,x;}aa[300003],bb[300001]; int t=0,a[300003],b[300003],l[300003],r[300003],c[300003]; bool panduan(int x,int y) { if(aa[x].x>aa[y].x||(aa[x].x==aa[y].x&&aa[x].l<aa[y].l))return 1; return 0; } void gouzao(int v) { if(v==1)return; if(panduan(v,v/2))std::swap(aa[v],aa[v/2]),gouzao(v/2); } void xiugai(int v) { if(v*2>t)return; if(v*2==t){if(panduan(v*2,v))std::swap(aa[v],aa[v*2]);return;} if(!panduan(v*2,v)&&!panduan(v*2+1,v))return; if(panduan(v*2,v*2+1))std::swap(aa[v],aa[v*2]),xiugai(v*2); else std::swap(aa[v],aa[v*2+1]),xiugai(v*2+1); } int main() { int n,t1=0; std::string s; std::cin>>n>>s; for(int i=1;i<=n;i++) { std::cin>>a[i]; if(s[i-1]=='X')b[i]=1; } for(int i=1;i<n;i++) { l[i]=i-1,r[i]=i+1; if(b[i]==b[i+1])continue; aa[++t].l=i,aa[t].r=i+1,aa[t].x=a[i]+a[i+1],gouzao(t); } l[n]=n-1,r[n]=0; while(t) { if(!c[aa[1].l]&&!c[aa[1].r]) { int x=aa[1].l,y=aa[1].r; std::swap(aa[1],aa[t--]),xiugai(1); bb[++t1].l=x,bb[t1].r=y; c[x]=c[y]=1; int x1=l[x],y1=r[y]; if(!x1||!y1)continue; else { r[x1]=y1,l[y1]=x1; if(b[x1]!=b[y1])aa[++t].l=x1,aa[t].r=y1,aa[t].x=a[x1]+a[y1],gouzao(t); } } else std::swap(aa[1],aa[t--]),xiugai(1); } std::cout<<t1<<std::endl; for(int i=1;i<=t1;i++) { std::cout<<bb[i].l<<' '<<bb[i].r<<std::endl; } }
三角形
#include<bits/stdc++.h> using namespace std; int main(){ int ans=0,z=0; for(int j=4;j<=1000;j++){ int cnt=0; for(int k=1;k<j/2;k++){ if(((j*j-2*j*k)%(2*j-2*k))==0){ cnt++; } } if(cnt>z){ ans=j; z=cnt; } } cout<<ans<<endl; }
魔板
较难搜索
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> #include<queue> using namespace std; typedef long long LL; const int N = 8; queue <LL> que; string ans[50000]; char str1[10], str2[10]; bool vis[50000]; int map[10];//映射 int num[10]; LL fac[N];//阶乘 void change(int s[], int o){//o分别是0,1,2,表示ABC三种变化 switch(o){ case 0: for(int i = 0; i < 4; i ++) swap(s[i], s[8-i-1]); break; case 1: for(int i = 3; i >= 1; i --) swap(s[i], s[i-1]); for(int i = 4; i < 7; i ++) swap(s[i], s[i+1]); break; case 2: swap(s[1], s[6]); swap(s[6], s[5]); swap(s[5], s[2]); break; } } void cantor(int s[], LL num, int k){//康托展开,把一个数字num展开成一个数组s,k是数组长度 int t; bool h[k];//0到k-1,表示是否出现过 memset(h, 0, sizeof(h)); for(int i = 0; i < k; i ++){ t = num / fac[k-i-1]; num = num % fac[k-i-1]; for(int j = 0, pos = 0; ; j ++, pos ++){ if(h[pos]) j --; if(j == t){ h[pos] = true; s[i] = pos + 1; break; } } } } void inv_cantor(int s[], LL &num, int k){//康托逆展开,把一个数组s换算成一个数字num int cnt; num = 0; for(int i = 0; i < k; i ++){ cnt = 0; for(int j = i + 1; j < k; j ++){ if(s[i] > s[j]) cnt ++;//判断几个数小于它 } num += fac[k-i-1] * cnt; } } void init(){ fac[0] = 1; for(int i = 1; i < N; i ++) fac[i] = fac[i-1] * i; int a[8], b[8]; LL temp, temp2; que.push(0); vis[0] = true; while(!que.empty()){ LL temp = que.front(); que.pop(); cantor(a, temp, 8); for(int i = 0; i < 3; i ++){ copy(a, a+8, b); change(b, i); inv_cantor(b, temp2, 8); if(!vis[temp2]){ que.push(temp2); vis[temp2] = true; ans[temp2] = ans[temp] + (char)('A' + i); } } } } int main(){ init(); int T;std::cin>>T; while(T--){ scanf("%s%s", str1,str2); //先把所有初始状态都转换成12345678 //最终状态根据初始状态的转换而转换 //这样只要一次预处理就可以解决问题了 for(int i = 0; i < 8; i ++) map[str1[i] - '0'] = i + 1; for(int i = 0; i < 8; i ++) num[i] = map[str2[i] - '0']; LL temp; inv_cantor(num, temp, 8); cout << ans[temp] << endl; } }
A easy problem
矩阵快速幂
#include<set> #include<map> #include<cmath> #include<stack> #include<queue> #include<vector> #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #define maxn 6+5 #define clr(x,y) memset(x,y,sizeof(x)) using namespace std; const int inf = 0x3f3f3f3f; typedef long long ll; const double pi = acos( -1 ); //const ll mod = 1e9+7; int a[10]; ll k,m; ll qmul(ll a,ll b) { ll ans=0; while(b) { if(b&1)ans=(ans+a)%m; a=(a+a)%m; b>>=1; } return ans; } struct matrix { int n; ll maze[maxn][maxn]; void init(int n) { this->n=n; clr(maze,0); } matrix operator * (matrix & rhs) { matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+qmul(maze[i][k],rhs.maze[k][j]))%m; return ans; } }; matrix qlow(matrix a,ll n) { matrix ans; ans.init(a.n); for(int i=0;i<ans.n;i++)ans.maze[i][i]=1; while(n) { if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main() { //freopen("d:\\acm\\in.in","r",stdin); while(~scanf("%lld %lld",&k,&m)) { for(int i=0;i<10;i++) scanf("%d",&a[i]); if(k<10) { printf("%lld\n",k%m); continue; } matrix ans; ans.init(10); for(int i=0;i<10;i++)ans.maze[0][i]=i; matrix ant; ant.init(10); for(int i=0;i<9;i++)ant.maze[i+1][i]=1; for(int i=0;i<10;i++)ant.maze[i][9]=a[9-i]; matrix tmp; tmp=qlow(ant,k-9); ans=ans*tmp; printf("%lld\n",ans.maze[0][9]); } return 0; }
方程
#include <bits/stdc++.h> using namespace std; #define MAXN 9999 #define MAXSIZE 1010 #define DLEN 4 class BigNum { private: int a[500]; //可以控制大数的位数 int len; public: BigNum() { len=1; //构造函数 memset(a,0,sizeof(a)); } BigNum(const int); //将一个int类型的变量转化成大数 BigNum(const char*); //将一个字符串类型的变量转化为大数 BigNum(const BigNum &); //拷贝构造函数 BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算 friend istream& operator>>(istream&,BigNum&); //重载输入运算符 friend ostream& operator<<(ostream&,BigNum&); //重载输出运算符 BigNum operator+(const BigNum &)const; //重载加法运算符,两个大数之间的相加运算 BigNum operator-(const BigNum &)const; //重载减法运算符,两个大数之间的相减运算 BigNum operator*(const BigNum &)const; //重载乘法运算符,两个大数之间的相乘运算 BigNum operator/(const int &)const; //重载除法运算符,大数对一个整数进行相除运算 BigNum operator^(const int &)const; //大数的n次方运算 int operator%(const int &)const; //大数对一个int类型的变量进行取模运算 bool operator>(const BigNum &T)const; //大数和另一个大数的大小比较 bool operator>(const int &t)const; //大数和一个int类型的变量的大小比较 void print(); //输出大数 }; BigNum::BigNum(const int b) //将一个int类型的变量转化为大数 { int c,d=b; len=0; memset(a,0,sizeof(a)); while(d>MAXN) { c=d-(d/(MAXN+1))*(MAXN+1); d=d/(MAXN+1); a[len++]=c; } a[len++]=d; } BigNum::BigNum(const char *s) //将一个字符串类型的变量转化为大数 { int t,k,index,L,i; memset(a,0,sizeof(a)); L=strlen(s); len=L/DLEN; if(L%DLEN)len++; index=0; for(i=L-1; i>=0; i-=DLEN) { t=0; k=i-DLEN+1; if(k<0)k=0; for(int j=k; j<=i; j++) t=t*10+s[j]-'0'; a[index++]=t; } } BigNum::BigNum(const BigNum &T):len(T.len) //拷贝构造函数 { int i; memset(a,0,sizeof(a)); for(i=0; i<len; i++) a[i]=T.a[i]; } BigNum & BigNum::operator=(const BigNum &n) //重载赋值运算符,大数之间赋值运算 { int i; len=n.len; memset(a,0,sizeof(a)); for(i=0; i<len; i++) a[i]=n.a[i]; return *this; } istream& operator>>(istream &in,BigNum &b) { char ch[MAXSIZE*4]; int i=-1; in>>ch; int L=strlen(ch); int count=0,sum=0; for(i=L-1; i>=0;) { sum=0; int t=1; for(int j=0; j<4&&i>=0; j++,i--,t*=10) { sum+=(ch[i]-'0')*t; } b.a[count]=sum; count++; } b.len=count++; return in; } ostream& operator<<(ostream& out,BigNum& b) //重载输出运算符 { int i; cout<<b.a[b.len-1]; for(i=b.len-2; i>=0; i--) { printf("%04d",b.a[i]); } return out; } BigNum BigNum::operator+(const BigNum &T)const //两个大数之间的相加运算 { BigNum t(*this); int i,big; big=T.len>len?T.len:len; for(i=0; i<big; i++) { t.a[i]+=T.a[i]; if(t.a[i]>MAXN) { t.a[i+1]++; t.a[i]-=MAXN+1; } } if(t.a[big]!=0) t.len=big+1; else t.len=big; return t; } BigNum BigNum::operator-(const BigNum &T)const //两个大数之间的相减运算 { int i,j,big; bool flag; BigNum t1,t2; if(*this>T) { t1=*this; t2=T; flag=0; } else { t1=T; t2=*this; flag=1; } big=t1.len; for(i=0; i<big; i++) { if(t1.a[i]<t2.a[i]) { j=i+1; while(t1.a[j]==0) j++; t1.a[j--]--; while(j>i) t1.a[j--]+=MAXN; t1.a[i]+=MAXN+1-t2.a[i]; } else t1.a[i]-=t2.a[i]; } t1.len=big; while(t1.a[len-1]==0 && t1.len>1) { t1.len--; big--; } if(flag) t1.a[big-1]=0-t1.a[big-1]; return t1; } BigNum BigNum::operator*(const BigNum &T)const //两个大数之间的相乘 { BigNum ret; int i,j,up; int temp,temp1; for(i=0; i<len; i++) { up=0; for(j=0; j<T.len; j++) { temp=a[i]*T.a[j]+ret.a[i+j]+up; if(temp>MAXN) { temp1=temp-temp/(MAXN+1)*(MAXN+1); up=temp/(MAXN+1); ret.a[i+j]=temp1; } else { up=0; ret.a[i+j]=temp; } } if(up!=0) ret.a[i+j]=up; } ret.len=i+j; while(ret.a[ret.len-1]==0 && ret.len>1)ret.len--; return ret; } BigNum BigNum::operator/(const int &b)const //大数对一个整数进行相除运算 { BigNum ret; int i,down=0; for(i=len-1; i>=0; i--) { ret.a[i]=(a[i]+down*(MAXN+1))/b; down=a[i]+down*(MAXN+1)-ret.a[i]*b; } ret.len=len; while(ret.a[ret.len-1]==0 && ret.len>1) ret.len--; return ret; } int BigNum::operator%(const int &b)const //大数对一个 int类型的变量进行取模 { int i,d=0; for(i=len-1; i>=0; i--) d=((d*(MAXN+1))%b+a[i])%b; return d; } BigNum BigNum::operator^(const int &n)const //大数的n次方运算 { BigNum t,ret(1); int i; if(n<0)exit(-1); if(n==0)return 1; if(n==1)return *this; int m=n; while(m>1) { t=*this; for(i=1; (i<<1)<=m; i<<=1) t=t*t; m-=i; ret=ret*t; if(m==1)ret=ret*(*this); } return ret; } bool BigNum::operator>(const BigNum &T)const //大数和另一个大数的大小比较 { int ln; if(len>T.len)return true; else if(len==T.len) { ln=len-1; while(a[ln]==T.a[ln]&&ln>=0) ln--; if(ln>=0 && a[ln]>T.a[ln]) return true; else return false; } else return false; } bool BigNum::operator>(const int &t)const //大数和一个int类型的变量的大小比较 { BigNum b(t); return *this>b; } void BigNum::print() //输出大数 { int i; printf("%d",a[len-1]); for(i=len-2; i>=0; i--) printf("%04d",a[i]); printf("\n"); } // 以上kuangbin 大数模版 BigNum get_sol(int d){ double r=sqrt(d); unsigned long long a0=(unsigned long long)r; unsigned long long a=0; unsigned long long b=0,c=1; unsigned long long s=0; unsigned long long k[100]; k[0]=a0; b=a0*c-b; c=(d-b*b)/c; a=(b+a0)/c; s++; k[s]=a; while(a!=2*a0){ b=a*c-b; c=(d-b*b)/c; a=(b+a0)/c; s++; k[s]=a; } BigNum p,q; for(int i=s-1;i>=0;i--) { if(i==s-1){ p=1; q=k[i]; } else{ BigNum tmp=q; q=BigNum (k[i])*q+p; p=tmp; } } BigNum x; if(s%2==0) x=q; else x=q*q*2+1; return x; } int main(){ int n; cin>>n; BigNum ans=0; BigNum x; for(int d=2;d<=n;d++){ if(((unsigned long long)sqrt(d+0.5))*((unsigned long long)sqrt(d+0.5))==d) continue; x=get_sol(d); if(x>ans){ ans=x; } } cout<<ans<<endl; return 0; }
Fly
#include<bits/stdc++.h> using namespace std; int a[500010]; int dp[500010][15]; int maxn[15]; int main() { memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); memset(maxn,0,sizeof(maxn)); int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n+1;i++) { for(int j=0;j<=k;j++) dp[i][j]=dp[i-1][j]+a[i]; if(i>1)for(int j=0;j<=k;j++) dp[i][j]=max(dp[i][j],dp[i-2][j]+a[i]); for(int j=0;j<k;j++) dp[i][j+1]=max(dp[i][j+1],maxn[j]+a[i]); for(int j=0;j<k;j++) maxn[j]=max(maxn[j],dp[i][j]); } int ans=-2000000000; for(int i=0;i<=k;i++)ans=max(ans,dp[n+1][i]); printf("%d\n",ans); return 0; }
字符串
#include<bits/stdc++.h> using namespace std; char s[110]; int dp[110][110]; bool judge(int a,int lena,int b,int lenb) { while(lena&&lenb&&s[a+lena-1]==s[b+lenb-1]) lena--,lenb--; return lena==0; } string change(int x) { if(x==0) return "0"; string tmp=""; while(x) { tmp=tmp+(char)(x%10+'0'); x/=10; } reverse(tmp.begin(),tmp.end()); return tmp; } int cal(int x) { int tot=0; while(x) { x/=10; tot++; } return tot; } map<int,string> mp; string dfs(int l,int r) { if(mp.find(l*1000+r)!=mp.end()) { return mp[l*1000+r]; } if(r-l+1<4) { string tmp=""; for(int i=l;i<=r;i++) tmp=tmp+s[i]; mp[l*1000+r]=tmp; return tmp; } if(dp[l][r]!=(r-l+1)) { string tmp=""; string tmp1=dfs(l,l+dp[l][r]-1); if(tmp1.size()+2+cal(dp[l][r])<(r-l+1)) { tmp=tmp+change((r-l+1)/dp[l][r]); tmp=tmp+'('; tmp=tmp+tmp1; tmp=tmp+')'; } else { for(int i=l;i<=r;i++) tmp=tmp+s[i]; } mp[l*1000+r]=tmp; return tmp; } else{ string ans=""; int minans=r-l+2,minflag=r; for(int i=l;i<r;i++) { string tmp1=dfs(l,i); string tmp2=dfs(i+1,r); if(tmp1.size()+tmp2.size()<minans) { minans=tmp1.size()+tmp2.size(); ans=tmp1+tmp2; } } mp[l*1000+r]=ans; return ans; } } int main() { /* for(int cas=7;cas<8;cas++){ char infile[]="data0.in"; char outfile[]="data0.out"; infile[4]=cas+'0'; outfile[4]=cas+'0'; freopen(infile,"r",stdin); freopen(outfile,"w",stdout);*/ memset(s,0,sizeof(s)); memset(dp,0,sizeof(dp)); mp.clear(); scanf("%s",s+1); for(int i=0;i<110;i++) dp[i][i]=1; int n=strlen(s+1); for(int len=2;len<=n;len++) { for(int l=1;l<=n;l++) { int r=l+len-1; if(r>n) break; dp[l][r]=r-l+1; for(int k=l;k<=r;k++) { int la=k-l+1; int lb=len-la; if(la>lb) break; if(lb%la) continue; if(dp[k+1][r]==la) { if(judge(l,la,k+1,lb)) { dp[l][r]=min(dp[l][r],dp[k+1][r]); } } } } } cout<<(int)dfs(1,n).size()<<endl; return 0; }
异或和
规律自己打表可发现
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { long long n; cin>>n; if(n%4==3){ cout<<0<<endl; } else { if(n%4==0) cout<<n<<endl; if(n%4==1) cout<<(n^(n-1))<<endl; if(n%4==2) cout<<(n^(n-1)^(n-2))<<endl; } } return 0; }
正方形
智商题
#include<bits/stdc++.h> using namespace std; bool prime(long long x){ if(x==2) return 1; if(x%2==0) return 0; for(long long j=3;j*j<=x;j+=2){ if(x%j==0) return 0; } return 1; } int main(){ long long t; cin>>t; while(t--){ long long n,m; cin>>n>>m; if(n-m>1){ cout<<"NO"<<endl; }else{ if(prime(n+m)){ cout<<"YES"<<endl; }else{ cout<<"NO"<<endl; } } } }