初三奧賽模擬測試1

xrlong發表於2024-05-04

初三奧賽模擬測試1

  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);
    }
    
  2. T2 快速排序

    把程式碼粘下來用有 24pts

    在無 nan 時寫 sort 再得 12pts

    發現規律:

    沒有 nan 就是升序排列

    如果第一個是 nannan 在最前面,接著排後面的數。

    否則就把小於等於第一個數的都提前(包括第一個數),升序排好後再排後面的。

    堆顯然處理。

    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("");
    	}
    }
    
  3. 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);
    }
    
  4. T4 校門外歪脖樹上的鴿子

    類似 zkw 線段樹的更新,將左右兒子資訊互換,用樹剖維護。

    口胡的,沒寫。