初三奧賽模擬測試1
-
T1 迴文
暴力 \(dp\) 是 \(n^4\) 的。
類似傳紙條吧無用狀態去了就是 \(n^3\) 的
CODE
#include<bits/stdc++.h> using namespace std; using llt=long long; using llf=long double; using ull=unsigned long long; #define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c)) #define For_(i,a,b,c) for(int i=(a);i>=(b);i-=(c)) const int N=502,MOD=993244853; int n,m; unsigned int dp[N][N][N<<1]; char ca[N][N]; namespace IO{ template<class T> inline void write(T x){ static T st[45];T top=0;if(x<0)x=-x,putchar('-'); do{st[top++]=x%10;}while(x/=10);while(top)putchar(st[--top]^48); } template<class T = int> inline T read(T &x){ char s=getchar();x=0;bool pd=false;while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();} while('0'<=s&&s<='9'){x=x*10+(s^48),s=getchar();} return (pd?(x=-x):x); } } namespace IO{ inline char read(char &c){c=getchar();while(c<33||c>126) c=getchar();return c;} template<int MAXSIZE=INT_MAX> inline int read(char* c){ char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c[pos++]=s,s=getchar();c[pos]='\0';return pos; } template<int MAXSIZE=INT_MAX> inline int read(string &c){ c.clear();char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c.push_back(s),s=getchar(),pos++;return pos; } inline double read(double &x){scanf("%lf",&x);return x;} inline llf read(llf &x){scanf("%Lf",&x);return x;} template<class T,class... Args> inline void read(T& x,Args&... args){read(x);read(args...);} template<class T = int> inline T read(){T a;return read(a);} inline void write(char c){putchar(c);} inline void write(char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} inline void write(string &c){int len=c.size();For(i,0,len-1,1) putchar(c[i]);} inline void write(const char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} template<int PRECISION=6> inline void write(double x){printf("%.*lf",PRECISION,x);} template<int PRECISION=6> inline void write(llf x){printf("%.*Lf",PRECISION,x);} template<class T> inline void Write(T x){write(x),putchar(' ');} inline void Write(char c){write(c);if(c!='\n') putchar(' ');} inline void Write(char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} inline void Write(string &c){write(c);if(c[c.size()-1]!='\n') putchar(' ');} inline void Write(const char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);} template<class T,class... Args> inline void Write(T x,Args... args){Write(x);Write(args...);} } using namespace IO; #define Check(y) (y>0&&y<=m) int main(){ #ifndef ONLINE_JUDGE freopen("in_out/in.in","r",stdin); freopen("in_out/out.out","w",stdout); #endif read(n,m); For(i,1,n,1) For(j,1,m,1) read(ca[i][j]); int len=((n+m)>>1)+1; dp[2][1][n]=(ca[1][1]==ca[n][m]); For(i,3,len,1) For(xa,1,n,1) For_(xb,n,1,1){ int ya=i-xa,yb=m-(i-(n-xb+1))+1; if(!(Check(ya)&&Check(yb))) continue ; if(ca[xa][ya]==ca[xb][yb]) dp[i][xa][xb]+=(dp[i-1][xa][xb]+dp[i-1][xa-1][xb+1]+dp[i-1][xa-1][xb]+dp[i-1][xa][xb+1])%MOD; } int ans=0; if((n+m)&1) For(x,1,min(len-1,n),1) ans=(ans+dp[len][x][x]+dp[len][x][x+1])%MOD; else For(x,1,min(len-1,n),1) ans=(ans+dp[len][x][x])%MOD; write(ans); }
-
T2 快速排序
把程式碼粘下來用有 24pts
在無
nan
時寫sort
再得 12pts發現規律:
沒有
nan
就是升序排列如果第一個是
nan
,nan
在最前面,接著排後面的數。否則就把小於等於第一個數的都提前(包括第一個數),升序排好後再排後面的。
堆顯然處理。
CODE
#include<bits/stdc++.h> using namespace std; using llt=long long; using llf=long double; using ull=unsigned long long; #define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c)) #define For_(i,a,b,c) for(int i=(a);i>=(b);i-=(c)) const int N=5e5+4; int val[N]; priority_queue<int,vector<int>,greater<int> > que; namespace IO{ template<class T> inline void write(T x){ static T st[45];T top=0;if(x<0)x=-x,putchar('-'); do{st[top++]=x%10;}while(x/=10);while(top)putchar(st[--top]^48); } template<class T> inline T read(T &x){ char s=getchar();x=0;bool pd=false;while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();} while('0'<=s&&s<='9'){x=x*10+(s^48),s=getchar();} return (pd?(x=-x):x); } } namespace IO{ inline char read(char &c){c=getchar();while(c<33||c>126) c=getchar();return c;} template<int MAXSIZE=INT_MAX> inline int read(char* c){ char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c[pos++]=s,s=getchar();c[pos]='\0';return pos; } template<int MAXSIZE=INT_MAX> inline int read(string &c){ c.clear();char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c.push_back(s),s=getchar(),pos++;return pos; } inline double read(double &x){scanf("%lf",&x);return x;} inline long double read(long double &x){scanf("%Lf",&x);return x;} template<class T,class... Args> inline void read(T& x,Args&... args){read(x);read(args...);} template<class T=int> inline T read(){T a;return read(a);} inline void write(char c){putchar(c);} inline void write(char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} inline void write(string &c){int len=c.size();For(i,0,len-1,1) putchar(c[i]);} inline void write(const char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} template<int PRECISION=6> inline void write(double x){printf("%.*lf",PRECISION,x);} template<int PRECISION=6> inline void write(long double x){printf("%.*Lf",PRECISION,x);} template<class T> inline void Write(T x){write(x),putchar(' ');} inline void Write(char c){write(c);if(c!='\n') putchar(' ');} inline void Write(char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} inline void Write(string &c){write(c);if(c[c.size()-1]!='\n') putchar(' ');} inline void Write(const char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);} template<class T,class... Args> inline void Write(T x,Args... args){Write(x);Write(args...);} } using namespace IO; int main(){ #ifndef ONLINE_JUDGE freopen("in_out/in.in","r",stdin); freopen("in_out/out.out","w",stdout); #endif int t; read(t); while(t--){ int n; read(n); For(i,1,n,1){ string a; read(a); if(a=="nan") val[i]=-1; else val[i]=atoi(a.c_str()),que.push(val[i]); } For(i,1,n,1){ if(~val[i]){ while(que.top()<val[i]) Write(que.top()),que.pop(); if(!que.empty()&&val[i]==que.top()) Write(que.top()),que.pop(); }else Write("nan"); } while(!que.empty()) Write(que.top()),que.pop(); puts(""); } }
-
T3 混亂邪惡
題目已經告訴了做法題目的限制已經保證了有解。
考慮假貪心,將排序的序列隨機交換(或迴圈位移)跑,最多不到 10 次就有正解。
不會證,但也不太好卡。
題解挺強的做法,我沒看懂。
CODE
#include<bits/stdc++.h> using namespace std; using llt=long long; using llf=long double; using ull=unsigned long long; #define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c)) #define For_(i,a,b,c) for(int i=(a);i>=(b);i-=(c)) const int N=2e6+4; struct VAL{int val,id,ans;}c[N]; llt sum; namespace IO{ template<class T> inline void write(T x){ static T st[45];T top=0;if(x<0)x=-x,putchar('-'); do{st[top++]=x%10;}while(x/=10);while(top)putchar(st[--top]^48); } template<class T> inline T read(T &x){ char s=getchar();x=0;bool pd=false;while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();} while('0'<=s&&s<='9'){x=x*10+(s^48),s=getchar();} return (pd?(x=-x):x); } } namespace IO{ inline char read(char &c){c=getchar();while(c<33||c>126) c=getchar();return c;} template<int MAXSIZE=INT_MAX> inline int read(char* c){ char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c[pos++]=s,s=getchar();c[pos]='\0';return pos; } template<int MAXSIZE=INT_MAX> inline int read(string &c){ c.clear();char s=getchar();int pos=0;while(s<33||s>126) s=getchar(); while(s>=33&&s<=126&&pos<MAXSIZE) c.push_back(s),s=getchar(),pos++;return pos; } inline double read(double &x){scanf("%lf",&x);return x;} inline long double read(long double &x){scanf("%Lf",&x);return x;} template<class T,class... Args> inline void read(T& x,Args&... args){read(x);read(args...);} template<class T=int> inline T read(){T a;return read(a);} inline void write(char c){putchar(c);} inline void write(char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} inline void write(string &c){int len=c.size();For(i,0,len-1,1) putchar(c[i]);} inline void write(const char *c){int len=strlen(c);For(i,0,len-1,1) putchar(c[i]);} template<int PRECISION=6> inline void write(double x){printf("%.*lf",PRECISION,x);} template<int PRECISION=6> inline void write(long double x){printf("%.*Lf",PRECISION,x);} template<class T> inline void Write(T x){write(x),putchar(' ');} inline void Write(char c){write(c);if(c!='\n') putchar(' ');} inline void Write(char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} inline void Write(string &c){write(c);if(c[c.size()-1]!='\n') putchar(' ');} inline void Write(const char *c){write(c);if(c[strlen(c)-1]!='\n') putchar(' ');} template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);} template<class T,class... Args> inline void Write(T x,Args... args){Write(x);Write(args...);} } using namespace IO; mt19937 rnd(114514); inline bool cmp_val(VAL a,VAL b){return a.val>b.val;} inline bool cmp_id(VAL a,VAL b){return a.id<b.id;} inline bool check(int l,int r){ llt num=sum>>1; For(i,l,r,1){ if(num-c[i].val>=0) num-=c[i].val,c[i].ans=1; else c[i].ans=-1; } return !num; } int main(){ #ifndef ONLINE_JUDGE freopen("in_out/in.in","r",stdin); freopen("in_out/out.out","w",stdout); #endif int n,m,cnt=0;read(n,m); For(i,1,n,1) read(c[i].val),c[i].id=i,sum+=c[i].val; puts("NP-Hard solved"); int bg=1,ed=n; while(!check(bg,ed)) swap(c[rnd()%n+1],c[rnd()%n+1]),cnt++; cerr<<cnt<<endl; sort(c+bg,c+ed+1,cmp_id); For(i,bg,ed,1) Write(c[i].ans); }
-
T4 校門外歪脖樹上的鴿子
類似 zkw 線段樹的更新,將左右兒子資訊互換,用樹剖維護。
口胡的,沒寫。