2020ICPC上海 B.Mine Sweeper II(思維,亂搞)
題意:
掃雷,給你A,B圖。權值為所有非雷點的和,要求你修改B圖中不超過(n*m/2)個點,使得A,B圖權值相等。
思路:
感覺過的太多了,肯定不難。模擬發現,每個點變化值1,2,3,4…都有,所以大膽猜測一定有解,所以直接用優先佇列存下修改每個點造成的權值變化,然後每次取出最大(最小)的,來逼急差值,使得A,B儘可能相等。再更新周圍8個點。
寫的很噁心了。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 7;
char a[maxn][maxn],b[maxn][maxn];
int val[maxn][maxn],vis[maxn][maxn];
int dirx[] = {0,0,0,1,1,1,-1,-1,-1};
int diry[] = {0,1,-1,0,1,-1,0,1,-1};
int n,m;
struct Node { //mx
int x,y,v;
int id;
bool operator < (const Node&rhs) const {
if(v == rhs.v && id == rhs.id) return x + y < rhs.x + rhs.y;
return v < rhs.v;
}
};
struct Node2 { //mi
int x,y,v;
int id;
bool operator < (const Node2&rhs) const {
if(v == rhs.v && id == rhs.id) return x + y < rhs.x + rhs.y;
return v > rhs.v;
}
};
void Print() {
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
printf("%c",b[i][j]);
}
printf("\n");
}
}
priority_queue<Node>q;
priority_queue<Node2>q2;
void change(int x,int y,int flag) {
if(b[x][y] == '.') {
b[x][y] = 'X';
} else {
b[x][y] = '.';
}
int cnt = 0;
for(int d = 1;d <= 8;d++) {
int dx = x + dirx[d],dy = y + diry[d];
if(dx <= 0 || dy <= 0 || dx > n || dy > m) continue;
vis[dx][dy]++;
if(b[x][y] == b[dx][dy]) {
cnt++;
val[dx][dy] += 2;
} else {
cnt--;
val[dx][dy] -= 2;
}
if(!flag) {
q.push({dx, dy, val[dx][dy], vis[dx][dy]});
} else {
q2.push({dx, dy, val[dx][dy], vis[dx][dy]});
}
}
val[x][y] = cnt;
if(!flag) {
q.push({x,y,val[x][y],vis[x][y]});
} else {
q2.push({x,y,val[x][y],vis[x][y]});
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++){
scanf("%s",a[i] + 1);
}
for(int i = 1;i <= n;i++) {
scanf("%s",b[i] + 1);
}
int suma = 0,sumb = 0;
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
if(a[i][j] == 'X') continue;
int cnt = 0;
for(int d = 1;d <= 8;d++) {
int dx = i + dirx[d],dy = j + diry[d];
if(dx <= 0 || dy <= 0 || dx > n || dy > m) continue;
if(a[dx][dy] == 'X') cnt++;
}
suma += cnt;
}
}
int mine = 0;
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
if(b[i][j] == 'X') {
mine++;
}
int cnt = 0,cnt2 = 0;
for(int d = 1;d <= 8;d++) {
int dx = i + dirx[d],dy = j + diry[d];
if(dx <= 0 || dy <= 0 || dx > n || dy > m) continue;
if(b[dx][dy] == 'X') cnt++;
if(b[i][j] == b[dx][dy]) {
cnt2++;
} else {
cnt2--;
}
}
if(b[i][j] == '.') {
sumb += cnt;
}
val[i][j] = cnt2;
q.push({i,j,cnt2,0});
q2.push({i,j,cnt2,0});
}
}
if(suma == 0) {
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= m;j++) {
if(b[i][j] == 'X' && mine <= n * m / 2) {
b[i][j] = '.';
} else if(b[i][j] == '.' && mine > n * m / 2) {
b[i][j] = 'X';
}
}
}
} else {
int T = n * m * 2;
while(T) {
if(T <= 0 || suma == sumb) break;
if(sumb < suma) {
Node now = q.top();q.pop();
if(now.id < vis[now.x][now.y]) continue;
if(sumb + now.v <= suma) {
T--;
sumb += now.v;
change(now.x,now.y,0);
}
} else {
Node2 now = q2.top();q2.pop();
if(now.id < vis[now.x][now.y]) continue;
if(sumb + now.v >= suma) {
T--;
sumb += now.v;
change(now.x,now.y,1);
}
}
}
}
if(sumb == suma || suma == 0) Print();
else printf("-1\n");
return 0;
}
相關文章
- 2020 ICPC上海 B.Mine Sweeper II
- 2020ICPC上海 I Sky Garden(亂搞,思維)
- 2020ICPC 江西省賽 B. Apple(思維)APP
- Bitset 亂搞字串匹配字串匹配
- [技巧] 亂搞技巧 長期更新
- 【胡思亂想】JNI與執行緒池的維護執行緒
- 思維體系---技術思維、業務資料思維、產品思維、複合思維
- 淺析工具思維、產品思維、品牌思維與定位
- 求職思維和招聘思維求職
- 264、醜數 II | 演算法(leetcode,附思維導圖 + 全部解法)300題演算法LeetCode
- 把流量思維變成留量思維
- 40、組合總和 II | 演算法(leetode,附思維導圖 + 全部解法)300題演算法
- 框架思維框架
- 極思維
- 黑客思維黑客
- Python!請不要再亂搞 Linux 發行版了PythonLinux
- 劍指 Offer II 091、粉刷房子 | 演算法(leetcode,附思維導圖 + 全部解法)300題演算法LeetCode
- 關於浮動會錯亂的問題——轉換思維尋找替代方案
- 亂彈馬斯克與比爾蓋茲兩位首富的不同思維模式馬斯克模式
- 你是整體思維還是分析思維? - kentbeck
- 計算思維
- 模型思維(01)模型
- 基於亂搞做法的無害版 readme4.0
- 提升思維邏輯—SimpleMind Pro(思維導圖) for Mac/winMac
- 什麼是產品思維和專案思維? - Shreyas
- 《計算思維史話》思維導圖——持續更新
- 創新思維框架:第一原則思維 - Neil Kakkar框架
- 英語思維與物件導向分析思維的關係物件
- 運維工程師思維導圖運維工程師
- typora思維導圖
- 技術思維2
- 前端思維導圖前端
- Java思維理清思路Java
- HDU – 4811 – Ball (思維)
- 【胡思亂想】命令模式 與 Thread Runnable模式thread
- 程式碼之外系列第一:索證思維與索進思維
- 上海三思LED科技多維度助力第19屆杭州亞運會勝利舉辦
- Xmind使用教程:給思維導圖加水印 「Xmind思維導圖2023」