NOIP2021模擬賽10.12 題解


寫在前面的話

最近寫題的狀態一直不在,寫什么都掛,想法也有漏洞

T1

A. 「NOIP2021模擬賽五 A」Generator

通過觀察我們發現,將數列從大到小排序后,遇到的一個數

  • 如果他是一個素數,那么肯定是第 \(i\) 個素數演化而來的

  • 如果是一個合數,那么肯定是要分解的

因為 \(i\) 始終小於第 \(i\) 個素數,一個數的因數必定小於他本身

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+5,maxm=2750135;
int N,a[maxn],b[maxn],p[maxm],max_x,prm[maxm],vis[maxm],Q[maxm];
struct IO{
    static const int S=1<<21;
    char buf[S],*p1,*p2;int st[105],Top;
    ~IO(){clear();}
    inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
    inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
    inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='r');return *this;}
    template<typename T>inline IO&operator >> (T&x){
        x=0;bool f=0;char ch=gc();
        while(ch<'0'||ch>'9'){if(ch=='-') f^=1;ch=gc();}
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=gc();
        f?x=-x:0;return *this;
    }
    inline IO&operator << (const char c){pc(c);return *this;}
    template<typename T>inline IO&operator << (T x){
        if(x<0) pc('-'),x=-x;
        do{st[++st[0]]=x%10,x/=10;}while(x);
        while(st[0]) pc('0'+st[st[0]--]);return *this;
    }
}fin,fout;
inline void make_p(){
	for(int i=2;i<=max_x;i++){
		if(Q[i])continue;
		p[++p[0]]=i;prm[i]=p[0];
		for(int j=1;j*i<=max_x;j++){
			Q[i*j]=1;
		}
	}
	return ;
}
int max_p(int x){
	int sq=sqrt(x);
	for(int i=2;i<=sq;i++){
		if(x%i==0)return x/i;
	}
}
int main(){
	fin>>N;
	for(int i=1;i<=(N<<1);i++)fin>>b[i],vis[b[i]]++,max_x=max(max_x,b[i]);
	make_p();
	sort(b+1,b+1+(N<<1));
	for(int i=(N<<1);i;i--){
		if(!vis[b[i]])continue;
		if(prm[b[i]]&&vis[prm[b[i]]]){
			a[++a[0]]=prm[b[i]];
			vis[b[i]]--;vis[prm[b[i]]]--;
		}
		else{
			int now=max_p(b[i]);
			if(vis[now]){
				a[++a[0]]=b[i];
				vis[b[i]]--;vis[now]--;
			}
		}
	}
	sort(a+1,a+1+a[0]);
	for(int i=1;i<=a[0];i++){
		if(i!=a[0])fout<<a[i]<<' ';
		else fout<<a[i];
	}
	return 0;
}

T2

B. 「NOIP2021模擬賽五 B」Data deletion

我們先思考這個問題的弱化版,只有 \(AB\)

我們發現每次刪除 \(AA\)\(BB\) 也就是一個奇數位上的 \(A\) 和偶數位上的\(A\) ,\(B\) 同理

那么顯然奇數位上 \(A\) 的個數 \(=\) 偶數位上 \(A\) 的個數 ,\(B\) 同理

那么我們將奇數位上的 \(A\) 換成 \(B\), \(B\) 換成 \(A\) ,那么就變成 \(A\) 的個數等於 \(B\) 的個數,這一步很關鍵

由於修改后的串能和修改前的串一一對應,所以只需要求修改后串的個數就好了

我們可以枚舉 \(A\) 的個數,就可以得出 \(B\) 的個數和 \(C\) 的個數,但是這樣會算重

考慮用補集思想,用總的個數減去不可能的個數,顯然當 \(A\) 的個數 \(>n/2\) 時是不可能的

所以枚舉 \(A\) 的個數 \(i\),不可能的個數就是\(C_{n}^i\times 2^{n-i}\)

\(i\) 個隨便排,剩下的 \(n-i\) 個放 \(C\)\(B\)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e7+5;
const LL TT=998244353;
int N;
LL Fct[maxn],iFct[maxn],ans;
LL Pow(LL a,LL b){LL s=1,w=a;while(b){if(b&1)s=s*w%TT;w=w*w%TT;b>>=1;}return s;}
LL C(LL x,LL y){
	return Fct[x]*iFct[y]%TT*iFct[x-y]%TT;
}
int main(){
	freopen("B.in","r",stdin);
	freopen("B.out","w",stdout);
	cin>>N;
	Fct[0]=1;for(int i=1;i<=N;i++)Fct[i]=Fct[i-1]*i%TT;
	iFct[N]=Pow(Fct[N],TT-2);for(int i=N-1;~i;i--)iFct[i]=iFct[i+1]*(i+1)%TT;
	for(int i=(N>>1)+((N&1)==0);i<=N;i++){
		ans=(ans+C(N,i)*Pow(2,N-i)%TT)%TT;
	}
	ans=((Pow(3ll,N)-(ans<<1))%TT+TT)%TT;
	cout<<ans<<endl;
	return 0;
}

T3

C. 「NOIP2021模擬賽五 C」Play dominos

一道質量不是很高的構造題

我們手玩出 \(3,5,7\) 的情況

然后對於奇數,我們需要算出 \(n-5\) 的答案然后加上 \(5\) 的答案

對於偶數,我們將用\(n\%6\)分類

  • \(n\%6=0\)
x.aa......z.
x.bb......z.
y.cc......y.
y...aa....y.
z...bb....x.
z...cc....x.
.x....aa...z
.x....bb...z
.y....cc...y
.y......aa.y
.z......bb.x
.z......cc.x
  • \(n\%6=2\)
x.aa.......p..
x.bb.......p..
y..cc.......z.
y...aa......z.
z...bb......y.
z....cc.....y.
.x....aa....x.
.x....bb....x.
.y.....cc....z
.y......aa...z
.z......bb...y
.z.......cc..y
..p.......aa.x
..p.......bb.x
  • \(n%6=4\)
x.aa.........q..
x..bb........q..
y..cc........p..
y...aa.......p..
z....bb.......z.
z....cc.......z.
.x....aa......y.
.x.....bb.....y.
.y.....cc.....x.
.y......aa....x.
.z.......bb....z
.z.......cc....z
..p.......aa...y
..p........bb..y
..q........cc..x
..q.........aa.x

X朋的代碼:

#include<bits/stdc++.h>
using namespace std;
char 
A3[3][4]={"aab","b.b","baa"},
A4[4][5]={"aacd","bbcd","cdaa","cdbb"},
A5[5][6]={"aabba","b.cca","bd..b","ad..b","abbaa"},
A6[6][7]={"aabcc.","b.b..d","baa..d","cc.aab","..db.b","..dbaa"},
A7[7][8]={"aabb..x","b..cc.x","ba....y",".a..aay","..a..bz","..a..bz","xxyyzz."},
A8[8][9]={"abb...a.","acc...a.","b.aa...c","b..bb..c","c..cc..b","c...aa.b",".a...bba",".a...cca"};
const int N=1005;
char ans[N][N];bool flg;
int main(){
	int n;scanf("%d",&n);if(n<=2) return puts("-1")&0;
	if(n<=7){
		if(n==3) for(int i=0;i<3;i++) printf("%s\n",A3[i]);
		if(n==4) for(int i=0;i<4;i++) printf("%s\n",A4[i]);
		if(n==5) for(int i=0;i<5;i++) printf("%s\n",A5[i]);
		if(n==6) for(int i=0;i<6;i++) printf("%s\n",A6[i]);
		if(n==7) for(int i=0;i<7;i++) printf("%s\n",A7[i]);
		return 0;
	}else{
		if(n&1){
			n-=5;flg=1;
		}
		if(n%6==0) for(int t=0;t<n/6;t++){
			for(int i=0;i<6;i++)
			for(int j=0;j<6;j++) ans[t*6+i][t*6+j]=A6[i][j];
		}else for(int t=0;t<n/6;t++){
			for(int i=0;i<6;i++)
			for(int j=0;j<6;j++) ans[t*6+i][t*6+j]=A6[i][j];
		}
		if(n%6==2)
			for(int i=0;i<8;i++)
			for(int j=0;j<8;j++) ans[n/6*6-6+i][n/6*6-6+j]=A8[i][j];
		if(n%6==4)
			for(int i=0;i<4;i++)
			for(int j=0;j<4;j++) ans[n/6*6+i][n/6*6+j]=A4[i][j];
		if(flg){
			for(int i=0;i<5;i++)
			for(int j=0;j<5;j++) ans[n+i][n+j]=A5[i][j];
			n+=5;
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++) if(!ans[i][j]) ans[i][j]='.';
		printf("%s\n",ans[i]);
	}
	return 0;
}

T4

D. 「NOIP2021模擬賽五 D」Conjoint

題解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM