牛客國慶集訓派對Day6 B-Board
阿新 • • 發佈:2018-12-13
題解
①
假設n=5,有三列被加過,有一行被加過,
那麼我們依次遍歷每一行的最小值,
把行最小值減去,就能恢復行操作。
再依次遍歷每一列的最小值,
把列最小值減去,就能恢復列操作。
考慮,有五列被加過且一行被加過的情形。
那麼,行最小值,就不完全是行操作所導致了。
但是,我們這麼操作,可以使每行減去(行操作+每列均操作過的最小值)。
而這對行最小行元素而言,已經恢復了,其他元素也並沒有多減。
後續,我們再每一列找,已經有0元素的列就會被跳過。
而那些少減的列,就會因此被減去。
前提:把-1那個點改成0,多減的值,就是原本應該被減成0的值。
②
思路來源
考慮以下這種染色方案,將(i行+j列)%n染成同種顏色。
這樣我們每次操作的時候,每種顏色的權當且僅當被加一次。
如果n=1,特判為0。
如果n不等於1,
找到與標記點顏色不同的任一顏色,
使之與標記點顏色作差即可。
前提:標記點也需改為權值0。
程式碼①
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const double INF=0x3f3f3f3f; const int maxn=1e5+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<double,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int a[1005][1005],ex,ey; int main() { int n; sci(n); rep(i,0,n-1) { rep(j,0,n-1) { sci(a[i][j]); if(a[i][j]==-1) { ex=i,ey=j; a[i][j]=0; } } } rep(i,0,n-1) { int v=10001; rep(j,0,n-1) { if(ex==i&&ey==j)continue; v=min(v,a[i][j]); } rep(j,0,n-1)a[i][j]-=v; } rep(j,0,n-1) { int v=10001; rep(i,0,n-1) { if(ex==i&&ey==j)continue; v=min(v,a[i][j]); } rep(i,0,n-1)a[i][j]-=v; } printf("%d\n",-a[ex][ey]); return 0; }
程式碼②
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const double INF=0x3f3f3f3f; const int maxn=1e5+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<double,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int a[1005][1005],ex,ey,ans[1005]; int main() { bool flag=1; int n; sci(n); rep(i,0,n-1) { rep(j,0,n-1) { sci(a[i][j]); if(a[i][j]==-1) { ex=i,ey=j; a[i][j]=0; } ans[(i+j)%n]+=a[i][j]; } } if(n==1)puts("0"); else { rep(i,0,n-1) { if(i!=(ex+ey)%n) { printf("%d\n",ans[i]-ans[(ex+ey)%n]); break; } } } return 0; }