前情提要:
我是个大蒟蒻! 在 张左 @张佑 的帮助下,我差点AK USACO铜组,可惜这个T1卡了我好久……估计只有700多了……
题面:
USACO 2025 January Contest, Bronze
Problem 1. Astral Superposition
注意:本题的时间限制为 4 秒,通常限制的 2 倍。
Bessie 正在使用她超酷的望远镜拍摄夜空中所有星星的照片。她的望远镜能够拍摄到一张 N×N ( 1≤N≤1000 )的星星照片,其中每个像素是一颗星星或者空旷的天空。每颗星星可由恰好一个像素表示,并且没有两颗不同的星星位于同一像素内。
一夜之间,一些奇怪的事情发生在了天空中的星星之上。每颗星星要么消失,要么向右移动 A 像素,并且向下移动 B 像素( 0≤A,B≤N )。如果一颗星星消失或移动超出照片边界,它将不再出现在第二张照片中。
Bessie 在星星移动位置之前和之后拍了照片,但在 Mootoshop 中进行了一些实验后,她不小心将一张照片叠加到了另一张上。现在,她可以在两张照片都是天空的位置看到白色(white)像素,在星星仅存在于恰好一张照片的位置看到灰色(gray)像素,而在两张照片中都有星星的位置看到黑色(black)像素。Bessie 同时记得没有新的星星移动入第二张照片的范围,从而她的第一张照片包含了夜空中所有的星星。
对于 T ( 1≤T≤1000 )个独立的测试用例,给定最终的照片,求在移动事件发生之前天空中星星的最小可能数量。如果不存在星星的排列可以产生给定的最终照片,输出 −1 。
输入格式(从终端 / 标准输入读入):
输入的第一行包含 T ,以下为 T 个测试用例。
每个测试用例的第一行包含 N A B 。
以下 N 行,每行表示叠加后的照片的一行。从上到下第 i 行由一个字符串 ci,1ci,2…ci,N 表示,其中 ci,j∈{W,G,B} ,分别表示颜色为白色,灰色以及黑色。
输入保证所有测试用例的 N^2 之和不超过 10^7 。
输出格式(输出至终端 / 标准输出):
对于每一个测试用例,输出移动之前存在的星星的最小数量,或 −1 表示不可能。
输入样例:
1
3 0 0
WWB
BBB
GGG
输出样例:
7
在这个例子中,没有移动发生。第一张照片如下(. 表示天空,* 表示星星):
..*
***
***
第二张照片中最下方一行的星星都消失了,如下:
..*
***
...
这是产生叠加后照片的唯一方式,所以初始时星星的最小可能数量为 77。
输入样例:
3
5 1 2
GWGWW
WGWWW
WBWGW
WWWWW
WWGWW
3 1 1
WWW
WBW
WWW
3 1 0
GGB
GGW
WWW
输出样例:
4
-1
4
在第一个测试用例中,初始时至少有 4 颗星星。如果我们令 (r,c) 表示从上到下第 r 行和从左到右第 c 列的交点,一种可能性是它们最初位于 (1,1),(3,2),(2,2) 和 (1,3)。除了位于 (2,2) 的星星消失之外,其他所有星星都移动了。
在第二个测试用例中,在给定的移动方式下,没有任何初始照片中的星星排列可以产生中间的黑色像素。
在第三个测试用例中,初始时至少有 4 颗星星。一种可能性是它们最初位于 (1,1),(1,2),(1,3) 和 (2,1)。在第二张照片中,原先位于 (1,1) 的星星消失了,原先位于 (1,3) 的星星移出了照片边界。其他两颗星星向右移动了 1 像素。
测试点性质:
- 测试点 3:A=B=0。
- 测试点 4-7:A=1,B=0,N≤10。
- 测试点 8-9:A=1,B=0。
- 测试点 10-12:没有额外限制。
供题:Suhas Nagar
本蒟蒻的写法
#include<bits/stdc++.h>
using namespace std;
int n, a, b;
char mp[3005][3005];
int s[3005][3005];
int main(void)
{
int t;
cin >> t;
while (t--) {
int ans = 0;
cin >> n >> a >> b;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
if (mp[i][j] == 'G')s[i][j] = 1;
if (mp[i][j] == 'B')s[i][j] = 2;
if (mp[i][j] == 'W')s[i][j] = 0;
}
}
int vis = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (s[i][j] > 0) {
if (s[i + b][j + a] != 0 && (s[i + b + b][j + a + a] != 2 || (a == 0 && b == 0))) {
s[i + b][j + a]--;
}
ans++;
}
if (s[i][j] == 2) {
vis = 1;
break;
}
}
if (vis)break;
}
if (vis) cout << "-1\n";
else cout << ans << "\n";
}
return 0;
}
AC了三个点