A:
中文题意,直接说思路:
可以知道在n%m == 0 的时候可以全部翻转完,但当第一次翻转完之后B使坏一次就永远也翻不到,所以只有当n==m的时候是YES其他都是NO
代码:
#include
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b;
scanf("%d%d",&a,&b);
if(a != b) puts("No");
else puts("Yes");
}
}
B:
思路:
简单的计数dp,可以设 dp[i][j]表示的是你在第i轮凑到j数字的时候的方案数是多少,那么这个状态可以是从dp[i-1][j-a[i]] 和 dp[i-1][-j]分别加上a[i]和乘-1转移过来,所以加个和,由于666的性质,我们每次都让dp[][666]等于0就好了,因为a[i]有负数所以要加一个偏移量,这样开的数组大小将会达到 300 * 666*2,会炸内存,由dp[i]只能由dp[i-1]转移过来,所以我们可以用滚动数组优化一下
代码:
#include
using namespace std;
const int tot = 300 * 666;
const int MOD = 1e8+7;
int dp[2][tot*2+1000] , a[333];
int main()
{
int n;
scanf("%d",&n);
int sum = 0;
for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]) , sum += abs(a[i]);
int k = 0;
dp[0][tot] = 1;
for(int i = 1 ; i <= n ; i++)
{
k = k ^ 1;
for(int j = -tot ; j < tot ; j ++)
{
if(j + tot - a[i] >= 0) dp[k][j+tot] = dp[k^1][j+tot-a[i]];
if(tot - j >= 0) dp[k][j+tot] += dp[k^1][tot-j];
//dp[k][j+tot] = (dp[k^1][j+tot-a[i]] + dp[k^1][tot-j]) % MOD;
dp[k][j+tot] %= MOD;
}
dp[k][tot+666] = 0;
}
cout<
C:
思路:我们可以得出,最后这点都会被分成几个点集,然后每个点集都由一个总的权值,我们在点集中的某些点中设置一个路障就可以得到点集中所有的权值,所以我们的问题现在就变成了如何求这些点的点集,我们用并查集找到这些点集,并求这些点集的和,之后按照从大到小排序求前m个就好了,对了坑点是long long。
代码:
#include
using namespace std;
#define int long long
const int maxn = 1e5+10;
int p[maxn] , ans[maxn] , a[maxn];
int getf(int x)
{
return x == p[x] ? x : p[x] = getf(p[x]);
}
signed main()
{
int n,m,t;
scanf("%d%d",&n,&m);
for(int i = 1 ; i <= n ; i++) p[i] = i;
for(int i = 1 ; i <= n ; i++) scanf("%lld",&a[i]);
for(int i = 1 ; i <= n ; i++)
{
scanf("%lld",&t);
int dx = getf(t);
int dy = getf(i);
if(dx != dy)
{
p[dx] = dy;
}
}
for(int i = 1 ; i <= n ; i++) ans[getf(i)] += a[i];
sort(ans+1,ans+n+1,[](int a,int b){return a > b;});
int ANS = 0;
for(int i = 1 ; i <= m ; i++) ANS += ans[i];
cout<
D:
思路:可以发现,m只有20,那么总共的方案数其实也就(1<<20)个,我们把这n个数放到bfs里面跑一下,求出这n个数能够变成的所有数所需要的最小步数,之后用m减去最小步数就好了。 这里解释一下
int v = (u^(1< dis[u] + 1)
{
dis[v] = dis[u] + 1;
Q.push(v);
}
首先我们有u这个二进制数,我们现在由u这个数开始扩展,找到一个改变u的某一位之后两个异或会产生1的数字,那么假设u的第j位是0,那么我们就要找到一个数v除了第j位位1其他都是0的数,假设u的第j位是1相反,那么这个v就是 u^(1< 代码: F: 思路:拉一个求球冠的板子就ok了 代码: #include
#include