賽時心態崩了,0pts
遺憾離場……今天在學校冷靜思考了下。發現B題思路其實很簡單,不過A題怎麼也沒有想到,回來看了題解,其實思路也很簡單,不過是自己思考方向錯了。看來打比賽心態很重要,如果能冷靜下來思考結果會好很多。
果然演算法競賽不能被常理所束縛(笑)
A - 01 Matrix Again
行列從\(0\)開始,以\((i+j)\ mod\ n\)的值給每個格子編號,就像這樣:
我們發現任選其中\(m\)種編號的位置填上\(1\),得到的矩陣一定滿足條件。那麼具體在哪些編號上填\(1\)呢?
- 首先,輸入給定的格子所在的編號一定要填。
- 其次,只按照第\(1\)條,可能湊不夠\(m\)種,這種情況,就要在非輸入給定的格子編號中任意挑選若干個,能湊成\(m\)種編號就行。
賽後一直思考這道題沒有頭緒是因為我的方向錯了。當時我一直糾結於行和列的規律,卻沒有想到斜向考慮會如此簡單。
點選檢視程式碼
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main(){
cin>>n>>m;
vector<bool> vis(n);
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
x--,y--;
vis[(x+y)%n]=1;
}
vector<int> ans;
for(int i=0;i<n;i++) if(vis[i]) ans.push_back(i);
for(int i=0;i<n;i++) if(!vis[i]&&ans.size()<m) ans.push_back(i);
cout<<n*m<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int x=i,y=(ans[j]-i+n)%n;
cout<<x+1<<" "<<y+1<<endl;
}
}
return 0;
}
B - Simple Math 4
顯然的結論:
\(2^N\ mod\ (2^M-2^K)=2^{N-M+K}\ mod\ (2^M-2^K)\)。
所以迴圈直到\(N<M\)即可。這一步驟可以透過除法在\(O(1)\)的時間複雜度下解決。
接下來答案就是\(2^N\ mod\ 10\),根據\(N\ mod\ 4\)的結果有\(4\)種答案:\(2,4,8,6\),同樣是\(O(1)\)。
但是需要注意的是得特判一種情況:n==m-1&&m-k==1
。這意味著原式等於\(2^N\ mod\ 2^{M-1}\)。而\(N=M-1\),所以這種情況需要輸出\(0\)。
點選檢視程式碼
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,m,k;
int mo[4]={6,2,4,8};
signed main(){
cin>>t;
while(t--){
cin>>n>>m>>k;
if(n>=m) n-=((n-m)/(m-k)+1)*(m-k);
if(m-k==1&&n==m-1) cout<<"0\n";
else cout<<mo[n%4]<<"\n";
}
return 0;
}