zcmu 1603 卡斯丁狗的战舰帝国(并查集+模拟)
生活随笔
收集整理的這篇文章主要介紹了
zcmu 1603 卡斯丁狗的战舰帝国(并查集+模拟)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
思路:看到題目我只知道,普通的暴力模擬是不行的,但是不知道用什么辦法優(yōu)化,然后看到網(wǎng)上的大佬們用了并查集恍然大悟;
用并查集維護每條船攻擊后的根節(jié)點,最后輸出查詢位置的根節(jié)點就行,如果在期間存在該位置的根節(jié)點的下個位置的根節(jié)點也已經(jīng)沉了,說明所有的船都已經(jīng)沉了,退出循環(huán);
代碼如下:
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include<string> #include <cmath> #include<stack> using namespace std; int a[100050], b[100050]; int f[100050]; int find(int x) {if (x == f[x])//說明已經(jīng)是根節(jié)點了return x;elsereturn f[x] = find(f[x]);//如果不是根節(jié)點,則找它的父節(jié)點 }int main() {int n, m;while (~scanf("%d%d",&n,&m)){for (int i = 1; i <=n; i++)scanf("%d", &a[i]);for (int i = 1; i <= n; i++){scanf("%d", &b[i]);f[i] = i;}int flag = 0;f[n+1] = 1;//*****************這步很重要!!!!******************把最后一條船后面的位置設(shè)置成1,說明這個位置指向?qū)Ψ降牡谝粭l船//用來滿足條件中的:如果不存在,則攻擊最遠離 i 并且< i 沒有死亡的敵方戰(zhàn)艦。while(m--){if (flag)break;for (int i = 1; i <= n; i++){int t = find(i);a[t] -= b[i];if (a[t] <= 0)//如果i位上的根節(jié)點已經(jīng)沉沒了{int tt = find(t + 1);//找根節(jié)點的下個節(jié)點的根節(jié)點if (a[tt] <= 0)//說明該點的根節(jié)點已經(jīng)沉了,說明戰(zhàn)斗已經(jīng)勝利{flag = 1;break;}else{f[t] = tt;//如果沒有沉,說明戰(zhàn)斗還沒有結(jié)束,f[t]指向根節(jié)點}}}}int c;int i;scanf("%d", &c);while (c--){scanf("%d", &i);if (flag)printf("win\n");elseprintf("%d\n", find(i));}}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的zcmu 1603 卡斯丁狗的战舰帝国(并查集+模拟)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OV7725寄存器配置
- 下一篇: Dijkstra算法正确性证明