C构造有点意思。
A
题目要求找到ab满足x+ab=y,即ab=y-x,即寻找y-x的一对约束,先计算出y-x的值随后在sqrt(y-x)的范围内枚举y-x的约数。
#include<bits/stdc++.h> using namespace std; #define maxx 1000000 #define INF 0x3f3f3f3f #define int long long int x,y,t,a,b; signed main() { cin>>t; for(int i=1;i<=t;++i) { cin>>x>>y; int z=y-x; a=-1; b=-1; for(int i=1;i<=sqrt(z);++i) if(z%i==0) { a=i; b=z/i; break; } cout<<a<<" "<<b<<"\n"; } }B
观察样例,有4n*4n的正方形,对于前n行,第i行行首有n-i+1个.,行末有同样的.,对于接下来的2n行,第i行行首有n个*,行末有同样的*,对于剩下的n行是前n行的倒转。
using namespace std; #define maxx 1000000 #define INF 0x3f3f3f3f #define int long long int x,y,t,a,b,n; void print(int i,char c) { for(int j=1;j<=i;++j) cout<<c; } signed main() { cin>>n; //4n列,4n行 for(int i=1;i<=n;++i) { print(n-i+1,'.'); print(2*n+2*i-2,'*'); print(n-i+1,'.'); cout<<"\n"; } for(int i=1;i<=2*n;++i) { print(n,'*'); print(2*n,'.'); print(n,'*'); cout<<"\n"; } for(int i=n;i>=1;--i) { print(n-i+1,'.'); print(2*n+2*i-2,'*'); print(n-i+1,'.'); cout<<"\n"; } }
C
构造
将叶全部填奇数,剩下的为偶数是一种合法的构造。
将叶全部填奇数,剩下的为偶数是一种合法的构造。
首先这种填法一定是合法的,因为偶数乘奇/偶数均为偶数,只有叶为奇数,则叶父亲是偶数,相乘合法,其他的位置肯定合法。
另外这种填法能够使用全部数字,首先考虑一个满二叉树,这样肯定合法,因为满二叉树的叶结点比非叶多1,总结点数为奇数,而由此产生的排列奇数也比偶数多1,一致。
对于非满二叉树,考虑由满二叉树逐渐产生,若最深层只有一个结点是合法,因为此时排列加1,多了一个偶数,而按上述填法奇数不变,排列奇数也不变,再增加一个结点,排列多了一个奇数,按上述填法也多了一个奇数,逐步论证,总是合法的。
#include<bits/stdc++.h> using namespace std; #define maxx 1000000 #define INF 0x3f3f3f3f #define int long long int x,y,t,a,b,n; int all[maxx]; signed main() { cin>>n; //4n列,4n行 for(int i=1;i<=n;++i) if(2*i>n&&2*i+1>n) all[i]=1; int ji=-1; int ou=0; for(int i=1;i<=n;++i) { if(all[i]==1) ji=ji+2,cout<<ji<<" "; else ou=ou+2,cout<<ou<<" "; } }D
背包dp
常见的设计状态与转移,只是需要注意滚动数组。
#include<bits/stdc++.h> using namespace std; #define maxx 200000 #define INF 0x3f3f3f3f #define int long long #define mod 1000000007 int x,y,t,a,b,n,p; int dp[2][maxx][2][2]; //蓝,红 int pd[maxx]; int all[maxx]; string s; signed main() { cin>>n>>p>>s; //4n列,4n行 for(int i=0;i<s.size();++i) {if(s[i]=='B') pd[i+1]=0; else pd[i+1]=1;} for(int i=1;i<=n;++i) cin>>all[i]; dp[0][0][0][0]=1; for(int i=1;i<=n;++i) for(int j=0;j<=p;++j) {dp[i%2][j][0][0]=dp[(i-1)%2][j][0][0]; dp[i%2][j][0][1]=dp[(i-1)%2][j][0][1]; dp[i%2][j][1][0]=dp[(i-1)%2][j][1][0]; dp[i%2][j][1][1]=dp[(i-1)%2][j][1][1]; if(pd[i]==0&&j>=all[i]) {dp[i%2][j][1][0]=(dp[i%2][j][1][0]+dp[(i-1)%2][j-all[i]][0][0]+dp[(i-1)%2][j-all[i]][1][0])%mod; dp[i%2][j][1][1]=(dp[i%2][j][1][1]+dp[(i-1)%2][j-all[i]][0][1]+dp[(i-1)%2][j-all[i]][1][1])%mod; } else if(pd[i]==1&&j>=all[i]) {dp[i%2][j][0][1]=(dp[i%2][j][0][1]+dp[(i-1)%2][j-all[i]][0][0]+dp[(i-1)%2][j-all[i]][0][1])%mod; dp[i%2][j][1][1]=(dp[i%2][j][1][1]+dp[(i-1)%2][j-all[i]][1][0]+dp[(i-1)%2][j-all[i]][1][1])%mod; } } cout<<dp[n%2][p][1][1]; }