6.10
小红的数组查询(二)
本题与《A.小红的数组查询(一)》共享部分题目背景,但是所求内容不同,我们建议您重新阅读题面。
思路:
这题就是找多少个数(pan)之后开始重复,区间数大于他时就是这个数,小于他是就是他的区间数。
怎么查找临界值:
当(x+i*d)%p=p时,i*d%p==0;
所以i*d是d和p的最小公倍数(这样i才最小)=d*p/(d,p的最大公因数)
则i=p/(d,p的最大公因数);
但要注意p=1的特殊情况(我一开始就没考虑到),当p=1,无论d为多少都为1 0 0 0……
当l==1,r>1时,不同值有两个;其余都为一个。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int n,q;
unsigned long long d,p;
unsigned long long l, r;
unsigned long long MaxGongYinShu(unsigned long long i, unsigned long long j) {while (j > 0) {unsigned long long w =j;j = i % j;i=w;}return i;
}
int main(){ios::sync_with_stdio(false); // 禁用同步cin.tie(nullptr); // 解除cin与cout绑定cin >> d >> p;d %= p;unsigned long long pan;if (d == 0) {pan = 1;}else {pan = p / MaxGongYinShu( d, p);}cin >> q;while (q--) {cin >> l >> r;if (p == 1) {if (l == 1&&r-l+1>1) {cout << 2 << endl;}else {cout << 1<<endl;}}else if (r-l + 1 >= pan) {cout << pan << endl;}else {cout << r-l + 1<<endl;}}return 0;
}
小苯的序列染色
思路
这题我就是先讨论情况,再得出最后的规律,它的规律是
- 字符串的最后一个字符必须是 '0',因为任何染色操作的最后一个字符都是 '0'。
- 从后向前遍历字符串,对于每个 '1',如果它是字符串的第一个字符,它的下一个字符必须是 '1'。
- 对于其他位置的 '1',它必须能够被某个染色操作覆盖,即它的前一个字符或后一个字符必须存在另一个 '1',形成 "11" 模式。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
string s;
int n, t;
int main(){ios::sync_with_stdio(false); // 禁用同步cin.tie(nullptr); // 解除cin与cout绑定cin >> t;while (t--) {cin >> n;cin >> s;bool fu = true;;for (int i = n-1; i >= 0; i--) {if (i==n-1&&s[i] == '1') {fu = false;break;}else if(i==0&&s[i]=='1') {if (s[i + 1] == '0') {fu = false;break;}else {fu = true;}}else if (s[i] == '1') {if (s[i - 1] == '0' && s[i + 1] == '0') {fu = false;}else if(s[i - 1] == '1' || s[i + 1] == '1') {fu = true;}}}if (fu) {cout << "YES" << endl;}else {cout << "NO" << endl;}}return 0;
}
多米诺覆盖 XOR
问题描述
有一个 HH 行和 WW 列的网格。用 (i,j)(i,j) 表示从顶部第 ii 行和从左侧第 jj 列的单元格。
单元格 (i,j) (1≤i≤H,1≤j≤W)(i,j) (1≤i≤H,1≤j≤W) 上写有一个非负整数 Ai,jAi,j 。
让我们在网格上放置零个或多个多米诺骨牌。一个多米诺骨牌覆盖两个相邻的单元格,具体为以下配对之一:
- 单元格 (i,j)(i,j) 和 (i,j+1)(i,j+1) 用于 1≤i≤H,1≤j<W1≤i≤H,1≤j<W ;
- 单元格 (i,j)(i,j) 和 (i+1,j)(i+1,j) 用于 1≤i<H,1≤j≤W1≤i<H,1≤j≤W 。
没有单元格可以被超过一个多米诺骨牌覆盖。
对于多米诺骨牌的放置,将其分数定义为所有未被任何多米诺骨牌覆盖的单元格中写入的整数的按位异或。
求最大可能分数。
什么是按位异或?
约束条件
- 1≤H1≤H
- 1≤W1≤W
- HW≤20HW≤20
- 0≤Ai,j<2600≤Ai,j<260 (1≤i≤H, 1≤j≤W1≤i≤H, 1≤j≤W)
- 所有输入值都是整数。
输入
输入按照以下格式从标准输入给出:
HH WW
A1,1A1,1 A1,2A1,2 …… A1,WA1,W
A2,1A2,1 A2,2A2,2 …… A2,WA2,W
⋮⋮
AH,1AH,1 AH,2AH,2 …… AH,WAH,W
输出
输出答案。
样本输入 1Copy
复制
3 4
1 2 3 8
4 0 7 10
5 2 4 2
样本输出 1Copy
复制
15
网格如下:
例如,下面的布局得分为 1515 。
没有布局能获得 1616 或更高的分数,所以输出 15
。
示例输入 2Copy
复制
1 11
1 2 4 8 16 32 64 128 256 512 1024
示例输出 2 复制
复制
2047
你也可以选择不放骨牌。
示例输入 3Copy
复制
4 5
74832 16944 58683 32965 97236
52995 43262 51959 40883 58715
13846 24919 65627 11492 63264
29966 98452 75577 40415 77202
示例输出 3Copy
复制
131067
思路:
本题的关键在于枚举所有可能的多米诺骨牌放置方式,并计算未被覆盖的单元格的异或和。
由于 H×W≤20,DFS 是可行的。
通过 DFS 遍历所有可能的放置方式,并记录最大异或和,即可得到答案。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int h, w;
long long a[25][25];
bool b[25][25];
long long sumMAX = 0;
void dfs(int i, int j, long long sum) {bool ff = false;for (; i <= h; i++) {for (; j <= w; j++) {if (b[i][j]) {b[i][j] = false;sum^= a[i][j];dfs(i, j,sum);sum ^= a[i][j];b[i][j] = true;if (b[i][j + 1]) {b[i][j] = false;b[i][j + 1] = false;dfs(i, j, sum);b[i][j + 1] = true;b[i][j] = true;}if (b[i+1][j]) {b[i][j] = false;b[i+ 1][j] = false;dfs(i, j, sum);b[i + 1][j] = true;b[i][j] = true;}ff = true;break;}}if (i <= h) {j = 1;}if (ff) {break;}}if (i > h) {//cout << sum << endl;if (sumMAX < sum) {sumMAX=sum;}}
}
int main(){ios::sync_with_stdio(false); // 禁用同步cin.tie(nullptr); // 解除cin与cout绑定cin >> h >> w;for (int i = 1; i <= h; i++) {for (int j = 1; j <= w; j++) {cin >> a[i][j];}}for (int i = 0; i <= h + 1; i++) {for (int j = 0; j<= w+1 ; j++) {if (i == 0 || i == h + 1 || j == 0 || j == w + 1) {b[i][j] = false;}else {b[i][j] = true;}}}dfs(1, 1, 0);cout << sumMAX << endl;return 0;
}