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]; 
}