生活随笔
收集整理的這篇文章主要介紹了
8.18模拟:构造
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
前言
190分
100+0+60+30
明明是dfs專題
不太理想qwq
寫了三個dfs就離譜
最不滿意的是T2的爆零
其實分類討論一下是很可做的
而且暴力還因為沒開ll掛掉了…
不過畢竟構造題之前幾乎沒有做過
所以慢慢來吧
收獲
一些構造題的trick
調整法數學歸納法分類討論法從邊界極值等處縮小問題規模法亂七八糟法
考場
先看題
數學的石頭門困境重新江湖…
似乎就沒有啥可做的題
在zld寫在前面的難度指引+先寫T1的習慣下
先看T1
(到現在似乎說是先看題結果幾乎還是順序做…)
zld果然沒有騙我!
想到了把一個2*2的正方形作為基本單位單獨處理
每塊的最差處理次數也可以證明不超過4次
這樣就ok了
但當時就想到這題代碼實現可能會有些困難
應該又是道打表搬磚題
但奇怪的道路那題的陰間打表我都寫過去了我還怕這個?
所以piapia就開始敲
這題我利用遞歸轉移
自己感覺寫的還是非常優美的
只需要一個操作對應的兩個表和常規的4宮格tx數組即可
但我因為怕寫掛自己造數據和手算輸出用了好一段…
9:00
轉T2
這什么玩意…
我也有些被zld的難度提示嚇到了
覺得這題很可能需要按位考慮貪心的亂七八糟的
然后就越想越迷糊
最后直接開始開心的dfs
試圖拿30分走人(伏筆)
9:30
開T3
又是讓人沒什么想法的題目
有一點直覺本題似乎很可能不會無解
(因為沒有多測)
但推來推去也證明不出來
但是第二個30不超過2個討厭的約束條件倒是推出來必定可行的策略了
然后就寫了兩個部分分拿60走人
10:10
看T4
又是不知從何推起的神仙題目
搞了半天除了浪費了一堆驗算紙一無所獲
最后又是dfs了…
復盤
T1
啊這個燈泡我覺得我點的是針不戳
很簡潔
所以貼一下碼awa
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
const int N
=105;
const int mod
=1e9+7;
int n
,m
;
int a
[N
][N
];
int tot
;
typedef pair
<int,int>pr
;
pr q
[N
*N
<<2][4];
#define mkp make_pair
int dx
[5][5]={{},{0,0,1,1},{0,0,1,1},{0,-1,-1,0},{0,-1,-1,0}};
int dy
[5][5]={{},{0,1,0,1},{0,-1,-1,0},{0,0,1,1},{0,-1,0,-1}};
void work(int x
,int y
,int o
){
tot
++;for(int i
=1;i
<=3;i
++){
q
[tot
][i
]=mkp(x
+dx
[o
][i
],y
+dy
[o
][i
]);a
[x
+dx
[o
][i
]][y
+dy
[o
][i
]]^=1;}
}
int tx
[5]={0,0,0,1,1},ty
[5]={0,0,1,0,1};
void solve(int x
,int y
){int cnt
=a
[x
][y
]+a
[x
+1][y
]+a
[x
][y
+1]+a
[x
+1][y
+1];
if(cnt
==0) return;else if(cnt
==1){for(int i
=1;i
<=4;i
++){int nx
=x
+tx
[i
],ny
=y
+ty
[i
];if(!a
[nx
][ny
]){work(x
+tx
[i
],y
+ty
[i
],i
);solve(x
,y
);return;}}}else if(cnt
==2){for(int i
=1;i
<=4;i
++){int nx
=x
+tx
[i
],ny
=y
+ty
[i
];if(a
[nx
][ny
]){
work(nx
,ny
,i
);solve(x
,y
);return;}}}else if(cnt
==3){for(int i
=1;i
<=4;i
++){int nx
=x
+tx
[i
],ny
=y
+ty
[i
];if(!a
[nx
][ny
]){work(nx
,ny
,i
);solve(x
,y
);return;}}}else{work(x
,y
,1);solve(x
,y
);return;}
}
int main(){freopen("bulb.in","r",stdin);freopen("bulb.out","w",stdout);int t
;scanf("%d",&t
);while(t
--){scanf("%d%d",&n
,&m
);tot
=0;for(int i
=1;i
<=n
;i
++){for(int j
=1;j
<=m
;j
++) scanf("%1d",&a
[i
][j
]);}if(n
%2&&m
%2){if(a
[n
][m
]) work(n
-1,m
-1,1);}if(m
%2){for(int i
=1;i
<n
;i
+=2){if(a
[i
][m
]&&a
[i
+1][m
]) work(i
,m
-1,1);else if(a
[i
][m
]) work(i
+1,m
,4);else if(a
[i
+1][m
]) work(i
,m
,2);}}if(n
%2){for(int j
=1;j
<m
;j
+=2){if(a
[n
][j
]&&a
[n
][j
+1]) work(n
-1,j
,1);else if(a
[n
][j
]) work(n
,j
+1,4);else if(a
[n
][j
+1]) work(n
,j
,3);}}for(int i
=1;i
<=n
;i
+=2){for(int j
=1;j
<=m
;j
+=2) solve(i
,j
);} printf("%d\n",tot
);for(int i
=1;i
<=tot
;i
++){for(int j
=1;j
<=3;j
++) printf("%d %d ",q
[i
][j
].first
,q
[i
][j
].second
);printf("\n");}}return 0;
}
T2
本題的關鍵性質是
只要從一個偶數往上連續取4個它的異或和就是0了
從一個偶數往上連續數2個就是1
所以分類討論即可
但k=3和r=l+1且l為奇數的細節有點惡心
感覺可能考場上就是把這個性質想到了想切也沒那么容易qwq
T3
調整法
可以證明隨著不斷調整組內的討厭關系組數會越來越少
這樣就能夠證明一直處理下去一定能找到合法解了
T4
數學歸納法
這個東西就是看出來就看出來了…
當時感覺可能會用數學歸納法
但是歸納了半天歸納不出來…
把奇數消掉后變成2n-1的想法是關鍵
總結
構造畢竟是新題
做的比較少
關鍵是對關鍵性質的把握
明天放假了
好耶!
總結
以上是生活随笔為你收集整理的8.18模拟:构造的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。