atcoder regular 176 (ARC176) A、B题解
A
很容易有一个错误想法,就是行从1~n,列从1~n拿,这样,第三个样例,最后,第7行,第7列,需要都增加两个数,但是(7,7)这个位置只能有一个数。
我的做法是优先队列/set队列,每次选择行、列之中当前已经有的数目最少的(这样它们最需要添加),这样能保证,行列需要添加的,不会出现只能选择多个行列一样的情况。因为优先队列的特性,剩下需要添加2个数的行/列肯定是优先被选取,它在需要添加1个数的行/列之前。
看到有3分钟做完这道题的…… 题解……
原则就是不重复的选取数字。
看题解的代码,比看文字更能理解。k=(i+j)%n。选取多少组,i=0...n-1,然后j=(k-i+n)%n,使得i+j取模n等于对应的k。出现过的m个点,对应的k都要选,其它k就是任意选择,总之要选取m个k。
首先,这样可以选择m个k,每个k,i都是从0到n-1,所以每个行(i)都选取了m次。
其次,这样可以选择m个k,每个k,j都是从0到n-1(因为对于每个k,k不变,i=0...n-1,对应j也是0...n-1),所以每个列(j)都选取了m次。
同样的,因为对于出现的m个点,它们的k=(i+j)%n,这些k,都被用过。对于一个k,对于所有(i+j)%n=k的i,j都遍历了,所以对于出现的m个点,输出肯定也有。
这个是在已经设定的点小于等于m的时候才成立的。
比如样例1
4 2 1 4 3 2
output:
8 1 4 2 3 3 2 4 1 1 1 2 4 3 3 4 2
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdbool> 6 #include <string> 7 #include <algorithm> 8 #include <iostream> 9 #include <sstream> 10 #include <ctime> 11 #include <stack> 12 #include <vector> 13 #include <queue> 14 #include <set> 15 #include <map> 16 #include <array> 17 #include <bitset> 18 using namespace std; 19 #define LL long long 20 #define ULL unsigned long long 21 22 const LL mod_1=1e9+7; 23 const LL mod_2=998244353; 24 25 const double eps_1=1e-5; 26 const double eps_2=1e-10; 27 28 const int maxn=1e5+10; 29 30 int row[maxn], col[maxn]; 31 set<pair<int,int> > choose_col; 32 map<pair<int,int>, int > cannot; 33 34 int main() 35 { 36 int n,m,x,y,i,j,k,geshu; 37 set<pair<int,int> >::iterator z; 38 memset(row,0,sizeof(row)); 39 memset(col,0,sizeof(col)); 40 cannot.clear(); 41 choose_col.clear(); 42 43 scanf("%d%d",&n,&m); 44 45 printf("%d\n",n*m); 46 47 for (i=1;i<=m;i++) 48 { 49 scanf("%d%d",&x,&y); 50 row[x]++; 51 col[y]++; 52 cannot[make_pair(x,y)]=1; 53 printf("%d %d\n",x,y); 54 } 55 56 for (j=1;j<=n;j++) 57 if (col[j]!=m) 58 choose_col.insert(make_pair(col[y], j)); 59 60 for (i=1;i<=n;i++) 61 { 62 for (j=1;j<=m-row[i];j++) 63 { 64 for (z=choose_col.begin();z!=choose_col.end();z++) 65 { 66 geshu = z->first; 67 k = z->second; 68 if (cannot[ make_pair(i, k) ]==0) 69 { 70 choose_col.erase(make_pair(geshu, k) ); 71 cannot[make_pair(i, k)]=1; 72 col[k]++; 73 if (col[k]!=m) 74 choose_col.insert(make_pair(geshu+1, k)); 75 76 break; 77 } 78 79 } 80 printf("%d %d\n",i, k); 81 } 82 } 83 84 85 return 0; 86 } 87 /* 88 1 1 89 1 1 90 91 ====== 92 93 1 0 94 95 ====== 96 97 4 0 98 99 ====== 100 101 4 1 102 2 3 103 */
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdbool> 6 #include <string> 7 #include <algorithm> 8 #include <iostream> 9 #include <sstream> 10 #include <ctime> 11 #include <stack> 12 #include <vector> 13 #include <queue> 14 #include <set> 15 #include <map> 16 #include <array> 17 #include <bitset> 18 using namespace std; 19 #define LL long long 20 #define ULL unsigned long long 21 22 const LL mod_1=1e9+7; 23 const LL mod_2=998244353; 24 25 const double eps_1=1e-5; 26 const double eps_2=1e-10; 27 28 const int maxn=1e5+10; 29 30 int row[maxn], col[maxn]; 31 set<pair<int,int> > choose_col; 32 map<pair<int,int>, int > cannot; 33 34 int main() 35 { 36 int n,m,x,y,i,j,k,geshu; 37 set<pair<int,int> >::iterator z; 38 memset(row,0,sizeof(row)); 39 memset(col,0,sizeof(col)); 40 cannot.clear(); 41 choose_col.clear(); 42 43 scanf("%d%d",&n,&m); 44 45 printf("%d\n",n*m); 46 47 for (i=1;i<=m;i++) 48 { 49 scanf("%d%d",&x,&y); 50 row[x]++; 51 col[y]++; 52 cannot[make_pair(x,y)]=1; 53 printf("%d %d\n",x,y); 54 } 55 56 for (j=1;j<=n;j++) 57 if (col[j]!=m) 58 choose_col.insert(make_pair(col[y], j)); 59 60 for (i=1;i<=n;i++) 61 { 62 for (j=1;j<=m-row[i];j++) 63 { 64 for (z=choose_col.begin();z!=choose_col.end();z++) 65 { 66 geshu = z->first; 67 k = z->second; 68 if (cannot[ make_pair(i, k) ]==0) 69 break; 70 } 71 printf("%d %d\n",i, k); 72 choose_col.erase(make_pair(geshu, k) ); 73 cannot[make_pair(i, k)]=1; 74 75 col[k]++; 76 if (col[k]!=m) 77 choose_col.insert(make_pair(geshu+1, k)); 78 } 79 //cout<<"ok"<<endl; 80 } 81 82 83 return 0; 84 } 85 /* 86 1 1 87 1 1 88 89 ====== 90 91 1 0 92 93 ====== 94 95 4 0 96 97 ====== 98 99 4 1 100 2 3 101 */
题解的代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #if __has_include(<atcoder/all>) 4 #include <atcoder/all> 5 using namespace atcoder; 6 #endif 7 using ll = long long; 8 using ld = long double; 9 using ull = unsigned long long; 10 #define endl "\n" 11 typedef pair<int, int> Pii; 12 #define REP(i, n) for (int i = 0; i < (n); ++i) 13 #define REP3(i, m, n) for (int i = (m); (i) < int(n); ++ (i)) 14 #define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++) 15 #define ALL(x) begin(x), end(x) 16 #define rrep(i,a,b) for(int i=a;i>=b;i--) 17 #define fore(i,a) for(auto &i:a) 18 #define all(s) (s).begin(),(s).end() 19 #define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i) 20 #define drep(i, n) drep2(i, n, 0) 21 #define rever(vec) reverse(vec.begin(), vec.end()) 22 #define sor(vec) sort(vec.begin(), vec.end()) 23 #define fi first 24 #define FOR_(n) for (ll _ = 0; (_) < (ll)(n); ++(_)) 25 #define FOR(i, n) for (ll i = 0; (i) < (ll)(n); ++(i)) 26 #define se second 27 #define pb push_back 28 #define P pair<ll,ll> 29 #define PQminll priority_queue<ll, vector<ll>, greater<ll>> 30 #define PQmaxll priority_queue<ll,vector<ll>,less<ll>> 31 #define PQminP priority_queue<P, vector<P>, greater<P>> 32 #define PQmaxP priority_queue<P,vector<P>,less<P>> 33 #define NP next_permutation 34 //const ll mod = 1000000009; 35 const ll mod = 998244353; 36 //const ll mod = 1000000007; 37 const ll inf = 4100000000000000000ll; 38 const ld eps = ld(0.00000000001); 39 static const long double pi = 3.141592653589793; 40 template<class T>void vcin(vector<T> &n){for(int i=0;i<int(n.size());i++) cin>>n[i];} 41 template<class T,class K>void vcin(vector<T> &n,vector<K> &m){for(int i=0;i<int(n.size());i++) cin>>n[i]>>m[i];} 42 template<class T>void vcout(vector<T> &n){for(int i=0;i<int(n.size());i++){cout<<n[i]<<" ";}cout<<endl;} 43 template<class T>void vcin(vector<vector<T>> &n){for(int i=0;i<int(n.size());i++){for(int j=0;j<int(n[i].size());j++){cin>>n[i][j];}}} 44 template<class T>void vcout(vector<vector<T>> &n){for(int i=0;i<int(n.size());i++){for(int j=0;j<int(n[i].size());j++){cout<<n[i][j]<<" ";}cout<<endl;}cout<<endl;} 45 void yes(bool a){cout<<(a?"yes":"no")<<endl;} 46 void YES(bool a){cout<<(a?"YES":"NO")<<endl;} 47 void Yes(bool a){cout<<(a?"Yes":"No")<<endl;} 48 void possible(bool a){ cout<<(a?"possible":"impossible")<<endl; } 49 void Possible(bool a){ cout<<(a?"Possible":"Impossible")<<endl; } 50 void POSSIBLE(bool a){ cout<<(a?"POSSIBLE":"IMPOSSIBLE")<<endl; } 51 #define FOR_R(i, n) for (ll i = (ll)(n)-1; (i) >= 0; --(i)) 52 template<class T>auto min(const T& a){ return *min_element(all(a)); } 53 template<class T>auto max(const T& a){ return *max_element(all(a)); } 54 template<class T,class F>void print(pair<T,F> a){cout<<a.fi<<" "<<a.se<<endl;} 55 template<class T>bool chmax(T &a,const T b) { if (a<b) { a=b; return 1; } return 0;} 56 template<class T>bool chmin(T &a,const T b) { if (b<a) { a=b; return 1; } return 0;} 57 template<class T> void ifmin(T t,T u){if(t>u){cout<<-1<<endl;}else{cout<<t<<endl;}} 58 template<class T> void ifmax(T t,T u){if(t>u){cout<<-1<<endl;}else{cout<<t<<endl;}} 59 ll fastgcd(ll u,ll v){ll shl=0;while(u&&v&&u!=v){bool eu=!(u&1);bool ev=!(v&1);if(eu&&ev){++shl;u>>=1;v>>=1;}else if(eu&&!ev){u>>=1;}else if(!eu&&ev){v>>=1;}else if(u>=v){u=(u-v)>>1;}else{ll tmp=u;u=(v-u)>>1;v=tmp;}}return !u?v<<shl:u<<shl;} 60 ll modPow(ll a, ll n, ll mod) { if(mod==1) return 0;ll ret = 1; ll p = a % mod; while (n) { if (n & 1) ret = ret * p % mod; p = p * p % mod; n >>= 1; } return ret; } 61 vector<ll> divisor(ll x){ vector<ll> ans; for(ll i = 1; i * i <= x; i++){ if(x % i == 0) {ans.push_back(i); if(i*i!=x){ ans.push_back(x / ans[i]);}}}sor(ans); return ans; } 62 ll pop(ll x){return __builtin_popcountll(x);} 63 ll poplong(ll x){ll y=-1;while(x){x/=2;y++;}return y;} 64 P hyou(P a){ll x=fastgcd(abs(a.fi),abs(a.se));a.fi/=x;a.se/=x;if(a.se<0){a.fi*=-1;a.se*=-1;}return a;} 65 P Pplus(P a,P b){ return hyou({a.fi*b.se+b.fi*a.se,a.se*b.se});} 66 P Ptimes(P a,ll b){ return hyou({a.fi*b,a.se});} 67 P Ptimes(P a,P b){ return hyou({a.fi*b.fi,a.se*b.se});} 68 P Pminus(P a,P b){ return hyou({a.fi*b.se-b.fi*a.se,a.se*b.se});} 69 P Pgyaku(P a){ return hyou({a.se,a.fi});} 70 71 void cincout(){ 72 ios::sync_with_stdio(false); 73 std::cin.tie(nullptr); 74 cout<< fixed << setprecision(15); 75 } 76 77 int main(){ 78 cincout(); 79 ll n,m; 80 cin>>n>>m; 81 vector<ll> b(n); 82 for(int i=0;i<m;i++){ 83 ll x,y; 84 cin>>x>>y; 85 x--; 86 y--; 87 b[(x+y)%n]++; 88 } 89 vector<ll> c; 90 for(int i=0;i<n;i++) if(b[i]) c.pb(i); 91 for(int i=0;i<n;i++) if(b[i]==0&&c.size()<m) c.pb(i); 92 cout<<n*m<<endl; 93 for(int i=0;i<m;i++){ 94 for(int j=0;j<n;j++){ 95 ll x=j,y=(c[i]-j+n)%n; 96 cout<<x+1<<" "<<y+1<<endl; 97 } 98 } 99 }
B
把数字都看成2进制分析。
其实这道题比A好写得多。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdbool> 6 #include <string> 7 #include <algorithm> 8 #include <iostream> 9 #include <sstream> 10 #include <ctime> 11 #include <stack> 12 #include <vector> 13 #include <queue> 14 #include <set> 15 #include <map> 16 #include <array> 17 #include <bitset> 18 using namespace std; 19 #define LL long long 20 #define ULL unsigned long long 21 22 const LL mod_1=1e9+7; 23 const LL mod_2=998244353; 24 25 const double eps_1=1e-5; 26 const double eps_2=1e-10; 27 28 const int maxn=2e5+10; 29 30 LL xs[4]={6,2,4,8}; 31 32 int main() 33 { 34 LL T,n,k,m,r,restn, loop, cnt_zero; 35 cin>>T; 36 while (T--) 37 { 38 cin>>n>>m>>k; 39 r=m-k; 40 41 if (m==k+1) 42 { 43 ///2^n % 2^k 44 if (n<k) 45 cout<<xs[n%4]<<endl; 46 else 47 cout<<0<<endl; 48 continue; 49 } 50 if (n<m) 51 { 52 cout<<xs[n%4]<<endl; 53 continue; 54 } 55 56 restn = n-m; 57 58 loop = restn / r; 59 cnt_zero = n - r * loop; 60 if (cnt_zero>=m) 61 cnt_zero -= r; 62 63 cout<<xs[cnt_zero%4]<<endl; 64 } 65 66 return 0; 67 } 68 /* 69 7 5 4 70 3 5 4 71 4 5 4 72 4 5 3 73 1 5 3 74 75 1 2 1 76 1 3 2 77 78 79 10 6 2 80 */