寫在前面的話
最近寫題的狀態一直不在,寫什么都掛,想法也有漏洞
T1
通過觀察我們發現,將數列從大到小排序后,遇到的一個數
-
如果他是一個素數,那么肯定是第 \(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;
}