《寒假每日一题 2022》
1960. 闪烁
题目链接
https://www.acwing.com/problem/content/1962/
分析
- 状态压缩:将二进制转化为十进制
- 状态转移:在十进制状态下进行转移
int last = num & 1; int temp = (num >> 1) + (last << n - 1); num = num ^ temp;
- 计算答案(容易出错,算明白了再写,尤其注意T=1的情况)
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
map<ll, bool> st;
map<ll, ll> tt;
map<ll, ll> ans;
ll n, t;
int main()
{
scanf("%lld%lld", &n, &t);
ll num = 0;
for(int i = 0; i < n; i ++){
int x;
scanf("%d", &x);
num = num * 2 + x;
}
//st[num] = true;
//tt[num] = 0;
//ans[0] = num;
bool flag = true;
int stop = 0;
for(int i = 1; i <= t; i ++){
int last = num & 1;
int temp = (num >> 1) + (last << n - 1);
num = num ^ temp;
//cout << num << endl;
if(st[num]) {
stop = i;
flag = false;
break;
}
st[num] = true;
tt[num] = i;
ans[i] = num;
}
if(flag == false){
ll tag = tt[num];
ll T = stop - tag;
ll res;
if(T == 1) res = stop - 1;
else res = (t - tag + 1) % T + tag - 1;
//cout << tag << ' ' << t << ' ' << stop << endl;
num = ans[res];
}
for(int i = n - 1; i >= 0; i --){
int x = (num >> i) & 1;
printf("%d\n", x);
}
return 0;
}
1945. 奶牛棒球
题目链接
https://www.acwing.com/problem/content/1947/
解析
暴力枚举x、z(z > x),二分查找是否有满足条件的y,一直x、z后y的范围很容易推。
y的范围可以用double表示,不用考虑取整问题。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
typedef long long ll;
int a[N];
int n;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
ll ans = 0;
for(int i = 1; i <= n; i ++){
for(int j = i + 1; j <= n; j ++){
int x = a[i], z = a[j];
//cout << x << ' ' << z << endl;
double left = (double)(2 * x + z) / 3.0, right = (double)(x + z) / 2.0;
//cout << left << ' ' << right << endl;
int l = i, r = j;
while (l < r) {
int mid = l + r >> 1;
if ((double)a[mid] >= left) r = mid;
else l = mid + 1;
}
int ll = l;
l = i, r = j;
while (l < r)
{
int mid = l + r + 1 >> 1;
if ((double)a[mid] <= right) l = mid;
else r = mid - 1;
}
int rr = l;
//cout << ll << ' ' << rr << endl;
ans += max(0, rr - ll + 1);
//puts("");
}
}
printf("%lld\n", ans);
return 0;
}
1934. 贝茜放慢脚步
题目链接
https://www.acwing.com/problem/content/1936/
解析
问题的本质是做一个两路归并,写代码的时候要明确需要维护的值,对于每一个要减慢速度的点,我们应当记录在减慢速度前已消耗的时间T和已走过的路程S,同时注意
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 1e4 + 10;
double tt[N], dd[N];
double T, S;
char op;
int tidx, didx, n;
int main()
{
scanf("%d\n", &n);
while(n --){
double x;
scanf("%c %lf\n", &op, &x);
//cout << op << ' ' << x << endl;
if(op == 'T') tt[tidx ++] = x;
else dd[didx ++] = x;
}
sort(tt, tt + tidx);
sort(dd, dd + didx);
int k = 1, i = 0, j = 0;
while(i < tidx && j < didx){
double td = (dd[j] - S) * k;
if(td < tt[i] - T){
T += td;
S = dd[j];
k ++, j ++;
}
else{
S += (tt[i] - T) / (double)k;
T = tt[i];
k ++, i ++;
}
}
while(i < tidx){
S += (tt[i] - T) / (double)k;
T = tt[i];
k ++, i ++;
}
while(j < didx){
T += (dd[j] - S) * k;
S = dd[j];
k ++, j ++;
}
T += (1000 - S) * k;
printf("%.0lf\n", round(T));
return 0;
}
1922. 懒惰的牛
题目链接
https://www.acwing.com/activity/content/problem/content/6539/
解析
- 注意的范围不利于做前缀和处理,所以整体+1
- 有点离散话的意思,不要把数据范围看花眼了
- mmax好像不可以用N直接替代,感觉有点奇怪。。。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e7 + 10;
int a[N];
ll s[N];
int n, k;
int main()
{
scanf("%d%d", &n, &k);
int mmax = 0;
for(int i = 1; i <= n; i ++) {
int x, y;
scanf("%d%d", &y, &x);
a[x + 1] = y;
mmax = max(mmax, x + 1);
}
for(int i = 1; i <= mmax; i ++) s[i] = s[i - 1] + a[i];
ll ans = 0;
for(int i = 1; i <= mmax; i ++){
int l = max(1, i - k), r = min(mmax, i + k);
ans = max(ans, s[r] - s[l - 1]);
}
printf("%lld\n", ans);
return 0;
}
1913. 公平摄影
题目链接
https://www.acwing.com/problem/content/1915/
解析
题目表述不清晰,关于题目的分析:
https://www.acwing.com/solution/content/85524/
具体做法:
比较巧妙的一点是将两种牛的tag设置为1、-1,原题转化为哪些段的和为0,有两种情况:
-
s[i] = 0, 从第一头牛到第i头牛和为0
-
s[i] = s[j] != 0, 从 i + 1 到 j 和为 0
这两种情况可以合并,可以通过设s[0] = 0实现
由于数据范围问题,通过pair和map来存储数据;
只包含一种牛的情况用双指针来做,代码写的不够熟练,主要是由于对于循环终止状态不够清晰。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;
typedef pair<ll, ll> PII;
int n;
PII a[N];
ll s[N];
map<ll, bool> st;
map<ll, ll> pos;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
{
ll x;
char op;
scanf("%lld %c\n", &x, &op);
if(op == 'G') a[i] = {x, 1};
else a[i] = {x, -1};
}
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; i ++)
s[i] = s[i - 1] + a[i].second;
//printf("%d ", s[i]); //s的范围是1-n
ll ans = 0;
for(int i = 1; i <= n; i ++){
if(s[i] == 0) ans = max(ans, a[i].first - a[1].first);
else{
if(!st[s[i]]) {
st[s[i]] = true;
pos[s[i]] = i;
}
else{
ans = max(ans, a[i].first - a[pos[s[i]] + 1].first);
}
}
}
ll res = 0, i = 1;
while(i <= n && a[i].second != -1) i ++;
while(i <= n){
int j = i;
while(j <= n && a[j].second != 1) j ++;
res = max(res, a[j - 1].first - a[i].first);
//printf("%lld ", res);
while(j <= n && a[j].second != -1) j ++;
i = j;
}
ans = max(ans, res);
res = 0, i = 1;
while(i <= n && a[i].second != 1) i ++;
while(i <= n){
int j = i;
while(j <= n && a[j].second != -1) j ++;
res = max(res, a[j - 1].first - a[i].first);
//printf("%lld ", res);
while(j <= n && a[j].second != 1) j ++;
i = j;
}
ans = max(ans, res);
//puts("");
//printf("%lld %lld\n", ans, res);
printf("%lld\n", ans);
return 0;
}
1904. 奶牛慢跑
题目链接
https://www.acwing.com/activity/content/problem/content/6541/
解析
用栈挺好的,但是懒得搞了,写了个离散化for了一遍也可以
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 1e5 + 10;
typedef pair<int, int> PII;
int n;
PII a[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
int x, v;
scanf("%d%d", &x, &v);
a[i] = {x, v};
}
int cnt = 0, vv = a[n].second;
for(int i = n; i >= 1; i --){
if(a[i].second <= vv) cnt ++;
vv = min(vv, a[i].second);
}
printf("%d\n", cnt);
return 0;
}
1843. 圆形牛棚
题目链接
https://www.acwing.com/problem/content/1845/
解析
暴力
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int a[N];
int ans = 0x3f3f3f3f;
int n;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++){
int res = 0;
for(int j = 1; j <= n; j ++){
res += (j + n - i) % n * a[j];
}
ans = min(ans, res);
}
printf("%d\n", ans);
return 0;
}
1826. 农田缩减
题目链接
https://www.acwing.com/problem/content/1828/
解析
简单分类讨论,没想到除了longlong忘开没有错误,就是做的时候不想做,中间刷了1h视频。。。(对不起这个世界呜呜呜)
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 5e4 + 10;
typedef long long ll;
typedef pair<ll, ll> PII;
PII a[N], b[N];
ll xmin, xmax, ymin, ymax;
ll ans;
int n;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
int x, y;
scanf("%d%d", &x, &y);
a[i] = {x, y};
b[i] = {y, x};
}
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
xmin = a[1].first, xmax = a[n].first;
ymin = b[1].first, ymax = b[n].first;
//cout << xmin << ' ' << xmax << ' ' << ymin << ' ' << ymax << endl;
//情况一:去掉y最大的一点
ll ax = b[n].second, by = b[n].first;
ymax = b[n - 1].first;
if(ax == xmin) xmin = a[2].first;
if(ax == xmax) xmax = a[n - 1].first;
ans = (ymax - ymin) * (xmax - xmin);
//printf("%d\n", (ymax - ymin) * (xmax - xmin));
xmin = a[1].first, xmax = a[n].first;
ymin = b[1].first, ymax = b[n].first;
//情况二:去掉y最小的一点
ax = b[1].second, by = b[1].first;
ymin = b[2].first;
if(ax == xmin) xmin = a[2].first;
if(ax == xmax) xmax = a[n - 1].first;
ans = min(ans, (ymax - ymin) * (xmax - xmin));
//printf("%d\n", (ymax - ymin) * (xmax - xmin));
xmin = a[1].first, xmax = a[n].first;
ymin = b[1].first, ymax = b[n].first;
//情况三:去掉x最小的一点
ax = a[1].first, by = a[1].second;
xmin = a[2].first;
if(by == ymin) ymin = b[2].first;
if(by == ymax) ymax = b[n - 1].first;
ans = min(ans, (ymax - ymin) * (xmax - xmin));
//printf("%d\n", (ymax - ymin) * (xmax - xmin));
xmin = a[1].first, xmax = a[n].first;
ymin = b[1].first, ymax = b[n].first;
//情况四:去掉x最大的一点
ax = a[n].first, by = a[n].second;
xmax = a[n - 1].first;
if(by == ymin) ymin = b[2].first;
if(by == ymax) ymax = b[n - 1].first;
ans = min(ans, (ymax - ymin) * (xmax - xmin));
//printf("%d\n", (ymax - ymin) * (xmax - xmin));
printf("%lld\n", ans);
return 0;
}
1813. 方块游戏
题目链接
https://www.acwing.com/problem/content/1815/
解析
对于每个木块来说,因为要满足正面和反面两种情况,所以对于每个木块,所需要的字母个数是正反面对应字母个数的最大值,n个木块只要累加即可。
做题之前要分析分析,将目标问题化简,不要试图通过高级的方法搞暴力。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 30;
int a[N];
int cnt1[N], cnt2[N];
char s1[N], s2[N];
int n;
int main()
{
scanf("%d", &n);
while(n --)
{
scanf("%s %s", s1, s2);
memset(cnt1, 0, sizeof cnt1);
memset(cnt2, 0, sizeof cnt2);
int len = strlen(s1);
for(int i = 0; i < len; i ++) cnt1[s1[i] - 'a'] ++;
len = strlen(s2);
for(int i = 0; i < len; i ++) cnt2[s2[i] - 'a'] ++;
for(int i = 0; i < 26; i ++){
a[i] += max(cnt1[i], cnt2[i]);
}
}
for(int i = 0; i < 26; i ++) printf("%d\n", a[i]);
return 0;
}
1801. 蹄子剪刀布
题目链接
https://www.acwing.com/problem/content/1803/
解析
大力出奇迹,喜提一发Ac。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
typedef pair<int, int> PII;
int n;
int score[5];
PII a[N];
int check1(int a, int b){
if(a == 1 && b == 2) return 1;
if(a == 2 && b == 2) return 1;
if(a == 3 && b == 1) return 1;
if(a == b) return 0;
return 2;
}
int check2(int a, int b){
if(a == 1 && b == 3) return 1;
if(a == 2 && b == 1) return 1;
if(a == 3 && b == 2) return 1;
if(a == b) return 0;
return 2;
}
int check3(int a, int b){
if(a == 1 && b == 2) return 1;
if(a == 2 && b == 3) return 1;
if(a == 3 && b == 1) return 1;
if(a == b) return 0;
return 2;
}
int check4(int a, int b){
if(a == 1 && b == 3) return 1;
if(a == 2 && b == 1) return 1;
if(a == 3 && b == 2) return 1;
if(a == b) return 0;
return 2;
}
int check5(int a, int b){
if(a == 1 && b == 3) return 1;
if(a == 2 && b == 1) return 1;
if(a == 3 && b == 2) return 1;
if(a == b) return 0;
return 2;
}
int check6(int a, int b){
if(a == 1 && b == 2) return 1;
if(a == 2 && b == 3) return 1;
if(a == 3 && b == 1) return 1;
if(a == b) return 0;
return 2;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
int x, y;
scanf("%d%d", &x, &y);
a[i] = {x, y};
}
int ans = 0;
memset(score, 0, sizeof score);
for(int i = 1; i <= n; i ++){
int x = a[i].first, y = a[i].second;
score[check1(x, y)] ++;
}
ans = max(ans, score[1]);
memset(score, 0, sizeof score);
for(int i = 1; i <= n; i ++){
int x = a[i].first, y = a[i].second;
score[check2(x, y)] ++;
}
ans = max(ans, score[1]);
memset(score, 0, sizeof score);
for(int i = 1; i <= n; i ++){
int x = a[i].first, y = a[i].second;
score[check3(x, y)] ++;
}
ans = max(ans, score[1]);
memset(score, 0, sizeof score);
for(int i = 1; i <= n; i ++){
int x = a[i].first, y = a[i].second;
score[check4(x, y)] ++;
}
ans = max(ans, score[1]);
memset(score, 0, sizeof score);
for(int i = 1; i <= n; i ++){
int x = a[i].first, y = a[i].second;
score[check5(x, y)] ++;
}
ans = max(ans, score[1]);
memset(score, 0, sizeof score);
for(int i = 1; i <= n; i ++){
int x = a[i].first, y = a[i].second;
score[check6(x, y)] ++;
}
ans = max(ans, score[1]);
printf("%d\n",ans);
return 0;
}
1789. 牛为什么过马路II
题目链接
https://www.acwing.com/problem/content/1791/
解析
- 注意读题:AC和BC这种不算交叉
- 关于交叉的判断,就老老实实描述就行,可以模拟一下相对位置关系,不要偷懒
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 30;
int S[N], E[N];
bool st[N];
char s[N * 2];
int main()
{
scanf("%s", s);
for(int i = 0; i < 52; i ++){
if(!st[s[i] - 'A']){
S[s[i] - 'A'] = i;
st[s[i] - 'A'] = true;
}
else{
E[s[i] - 'A'] = i;
}
}
for(int i = 0; i < 26; i ++){
if(S[i] > E[i]){
swap(S[i], E[i]);
}
}
int cnt = 0;
for(int i = 0; i < 26; i ++){
for(int j = i + 1; j < 26; j ++){
if(S[i] < S[j] && E[i] > S[j] && E[i] < E[j]) cnt ++;
else if(S[j] < S[i] && E[j] > S[i] && E[j] < E[i]) cnt ++;
}
}
printf("%d\n", cnt);
return 0;
}
1776. 牛的基因组学
题目链接
https://www.acwing.com/problem/content/1778/
解析
暴力
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
bool cow1[N][5], cow0[N][5]; //ATCG
char a[N];
int n, m;
int main()
{
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i ++){
scanf("%s", a);
for(int j = 0; j < m; j ++){
if(a[j] == 'A') cow1[j][0] = true;
else if(a[j] == 'T') cow1[j][1] = true;
else if(a[j] == 'C') cow1[j][2] = true;
else if(a[j] == 'G') cow1[j][3] = true;
}
}
for(int i = 0; i < n; i ++){
scanf("%s", a);
for(int j = 0; j < m; j ++){
if(a[j] == 'A') cow0[j][0] = true;
else if(a[j] == 'T') cow0[j][1] = true;
else if(a[j] == 'C') cow0[j][2] = true;
else if(a[j] == 'G') cow0[j][3] = true;
}
}
int cnt = 0;
for(int i = 0; i < m; i ++){
bool flag = true;
for(int k = 0; k < 4; k ++){
if(cow1[i][k] && cow0[i][k]) flag = false;
}
if(flag) {
cnt ++;
}
}
printf("%d\n", cnt);
return 0;
}
1762. 牛的洗牌
题目链接
https://www.acwing.com/problem/content/1764/
解析
暴力。
题目稍微有点歧义,三次洗牌指令相同,即要操作三次。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int a[N];
string ans[N], b[N];
int n;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++){
string str;
cin >> str;
b[i] = str;
}
for(int i = 1; i <= n; i ++) ans[i] = b[a[i]];
for(int i = 1; i <= n; i ++) b[i] = ans[a[i]];
for(int i = 1; i <= n; i ++) ans[i] = b[a[i]];
for(int i = 1; i <= n; i ++) cout << ans[i] << endl;
return 0;
}
1750. 救生员
题目链接
https://www.acwing.com/activity/content/problem/content/6573/
*解析
理清思路直接写就行,没什么算法
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
typedef pair<int, int> PII;
int n;
PII a[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
int x, y;
scanf("%d%d", &x, &y);
a[i] = {x, y};
}
sort(a + 1, a + n + 1);
int res = 0;
for(int i = 1; i <= n; i ++){
int ans = 0;
int st = 0, ed = 0;
for(int j = 1; j <= n; j ++){
if(j == i) continue;
else{
if(a[j].first <= ed) ed = max(ed, a[j].second);
else{
ans += (ed - st);
st = a[j].first, ed = a[j].second;
}
}
}
ans += (ed - st);
res = max(res, ans);
}
printf("%d\n", res);
return 0;
}
1726. 挤奶顺序
题目链接
https://www.acwing.com/problem/content/description/1728/
解析
分类讨论:
- 奶牛1的位置确定
- 奶牛1的相对位置确定
- 奶牛1的位置和相对位置都不确定
第一种情况直接输出。
对于后两种情况,只考虑对相对位置给定的奶牛进行排序,在这些奶牛中,某些奶牛的位置可能是确定的,如果奶牛1的相对位置确定,则剩余相对位置确定而位置不确定的奶牛应该尽量往前排;如果奶牛1的相对位置不确定,则剩余相对位置确定而位置不确定的奶牛应该尽量往后排。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m, k;
int pos[N];
int a[N], b[N];
bool st[N];
int main()
{
scanf("%d%d%d", &n, &m, &k);
bool flag = true;
for(int i = 1; i <= m; i ++) {
scanf("%d", &a[i]);
if(a[i] == 1) flag = false;
}
for(int i = 0; i < k; i ++){
int x, y;
scanf("%d%d", &x, &y);
pos[x] = y;
st[y] = true;
//cout << x << ' ' << y << endl;
}
if(pos[1] != 0) printf("%d\n", pos[1]);
else if (flag) {
int idx = n;
for(int i = m; i > 0; i --){
if(pos[a[i]] != 0) {
idx = pos[a[i]] - 1;
}
else {
while(st[idx]) idx --;
pos[a[i]] = idx --;
}
}
//for(int i = 1; i <= m; i ++) printf("%d ", pos[a[i]]);
//puts("");
for(int i = 1; i <= n; i ++) b[pos[i]] = i;
int ans = 0;
for(int i = 1; i <= n; i ++){
if(b[i] == 0){
ans = i;
break;
}
}
printf("%d\n", ans);
}
else if(!flag){
int idx = 1;
for(int i = 1; i <= m; i ++){
if(pos[a[i]] != 0) {
idx = pos[a[i]] + 1;
}
else {
while(st[idx]) idx ++;
pos[a[i]] = idx ++;
}
}
int ans = pos[1];
printf("%d\n", ans);
}
return 0;
}
1696. 困牛排序
题目链接
https://www.acwing.com/problem/content/1698/
解析
数据范围100,写暴力就行,不要去想什么性质然后O(n)完成,没必要也没有,详情可见wa掉的例子。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int n;
int a[N];
bool check(int l, int r){
bool flag = true;
for(int i = l; i <= r; i ++){
if(a[i] > a[i + 1]) flag = false;
}
if(flag) return true;
return false;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
}
int ans = 0;
a[n + 1] = 0x3f3f3f3f;
for(int i = 1; i <= n; i ++){
if(check(i, n)) break;
else ans ++;
}
printf("%d\n", ans);
return 0;
}
1684. 大型植被恢复
题目链接
https://www.acwing.com/problem/content/1686/
解析
- 建图
- 搜索答案的顺序
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200;
int n, m;
int e[N], ne[N], h[N], idx;
bool st[5];
int ans[N], du[N];
void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
while(m --){
int l, r;
scanf("%d%d", &l, &r);
if(r < l) swap(l, r);
add(r, l);
du[r] ++;
}
for(int i = 1; i <= n; i ++){
if(du[i] == 0) {
ans[i] = 1;
}
else{
memset(st, 0, sizeof st);
for(int j = h[i]; j != -1; j = ne[j]){
int k = e[j];
st[ans[k]] = true;
}
for(int j = 1; j <= 4; j ++){
if(!st[j]){
ans[i] = j;
break;
}
}
}
}
for(int i = 1; i <= n; i ++)
if(!ans[i]) ans[i] = 1;
for(int i = 1; i <= n; i ++) printf("%d", ans[i]);
puts("");
return 0;
}
1460. 我在哪?
题目链接
https://www.acwing.com/problem/content/1462/
解析
写暴力,8好意思,感觉这种找最小值的也不太用二分,直接从最小的开始遍历就行。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 110;
int n;
string a;
map<string, bool> st;
bool check(int x){
for(int i = 0; i + x - 1 < n; i ++){
string s = "";
for(int j = 0; j < x; j ++) s = s + a[i + j];
//cout << s << endl;
if(st[s]) return false;
st[s] = true;
}
return true;
}
int main()
{
scanf("%d", &n);
cin >> a;
int ans = 0;
for(int i = 1; i <= n; i ++){
if(check(i)){
ans = i;
break;
}
}
printf("%d\n", ans);
return 0;
}
1443. 拍照
题目链接
https://www.acwing.com/problem/content/1445/
解析
初次思考不够细致,题目判断条件有两个:
- a中各个数组不重复
- a中各个数字为正数
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n;
int a[N], b[N];
bool st[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i < n; i ++) scanf("%d", &b[i]);
for(int i = b[1] - 1; i > 0; i --){
memset(st, 0, sizeof st);
a[1] = i;
bool flag = true;
for(int i = 2; i <= n; i ++){
int x = b[i - 1] - a[i - 1];
if(x <= 0) {
flag = false;
break;
}
else if(st[x]){
flag = false;
break;
}
else {
a[i] = x;
st[x] = true;
};
}
if(flag) break;
}
for(int i = 1; i <= n; i ++) printf("%d ", a[i]);
puts("");
return 0;
}
1672. 疯狂的科学家
题目链接
https://www.acwing.com/problem/content/1674/
解析
写得很顺利是因为实现类似功能的代码段我写过。
贪心题。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n;
char a[N], b[N];
int main()
{
scanf("%d", &n);
scanf("%s%s", a, b);
int cnt = 0;
for(int i = 0; i < n;){
int x = i;
while(a[x] != b[x]) x ++;
if(x != i) cnt ++;
while(a[x] == b[x]) x ++;
i = x;
}
printf("%d\n", cnt);
return 0;
}
1660. 社交距离II
题目链接
https://www.acwing.com/problem/content/1662/
解析
思路没错,就是代码写错了,真心建议怎么改也改不出来就输出中间结果模拟样例。枯萎ing...
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n;
PII a[N], b;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
int x, y;
scanf("%d%d", &x, &y);
a[i] = {x, y};
}
sort(a + 1, a + n + 1);
int dmax = 0x3f3f3f3f;
for(int i = 1; i < n; i ++){
if((!a[i].second && a[i + 1].second) || (a[i].second && !a[i + 1].second)){
dmax = min(dmax, a[i + 1].first - a[i].first);
}
}
dmax --;
int cnt = 0;
int last = - 0x3f3f3f3f;
for(int i = 1; i <= n; i ++){
if(!a[i].second) {
continue;
}
if(a[i].first - last > dmax) {
last = a[i].first;
cnt ++;
}
else{
last = a[i].first;
}
}
printf("%d\n", cnt);
return 0;
}
3347. 菊花链
题目链接
https://www.acwing.com/problem/content/3350/
解析
前缀和+暴力
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int n;
int a[N], s[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++) s[i] = s[i - 1] + a[i];
int cnt = 0;
for(int i = 1; i <= n; i ++){
for(int j = i; j <= n; j ++){
int sum = s[j] - s[i - 1];
if(sum % (j - i + 1) == 0){
int p = sum / (j - i + 1);
for(int k = i; k <= j; k ++){
if(a[k] == p){
cnt ++;
break;
}
}
}
}
}
printf("%d\n", cnt);
return 0;
}
1978. 奶牛过马路
题目链接
https://www.acwing.com/problem/content/1980/
解析
首先按照pair的第一维(x)排序,然后维护最大前缀和和最小后缀和,一条路径是安全的等价与这条路径对应的y大于它前面数的最大前缀和后面数的最小后缀。
Ac代码
点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int n;
PII a[N];
int m[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
int x, y;
scanf("%d%d", &x, &y);
a[i] = {x, y};
st[y] = false;
}
sort(a + 1, a + n + 1);
int ans = 0;
int sum = 0;
m[0] = -0x3f3f3f3f;
for(int i = 1; i <= n; i ++) m[i] = max(m[i - 1], a[i].second);
for(int i = 1; i <= n;){
int cnt = 0;
int x = m[i];
//printf("%d %d ", i, x);
while(m[i] == x) {
i ++, cnt ++;
}
printf("%d\n", cnt);
sum += cnt;
if(cnt == 1) ans ++;
}
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架