ABBYY Cup 2.0 - Easy
4時間のコンテストでした。
A.
n×nの行列の対角と中央の行と列にある数字をすべて足します。
普通に足して、中央の数字の3倍を引いても良いです。
int g[128][128]; int main(){ int n,ans = 0; cin>>n; for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ cin>>g[i][j]; } } //main diagonal for(int i = 0; i < n; i++){ ans += g[i][i]; g[i][i] = 0; } //secondary diagonal for(int i = 0; i < n; i++){ ans += g[i][n-i-1]; g[i][n-i-1] = 0; } //middle row for(int i = 0; i < n; i++){ ans += g[n/2][i]; g[n/2][i] = 0; } //middle column for(int i = 0; i < n; i++){ ans += g[i][n/2]; g[i][n/2] = 0; } cout<<ans<<endl; return 0; }
B.
小さい方から素因数分解します。
√n以下の素数でnを割ると、√nより大きい素因数だけが残るので、O(√n)で計算できます。
typedef long long ll; int main(){ int n,n2; ll ans = 0; cin>>n; n2 = n; while(!(n&1)){ ans += n; n >>= 1; } for(int i = 3; i*i <= n2; i+=2){ while(!(n%i)){ ans += n; n /= i; } } if(n-1){ ans += n; } cout<<ans+1<<endl; return 0; }
C.
Union-Find木を書くだけです。
struct UF { int par[2000],rank[2000]; void init(int n){ for(int i = 0; i < n; i++){ par[i] = i; rank[i] = 0; } } int find(int x){ if(par[x] == x){ return x; }else{ return par[x] = find(par[x]); } } void unite(int x, int y){ x = find(x); y = find(y); if(x == y) return; if(rank[x] < rank[y]){ par[x] = y; }else{ par[y] = par[x]; if(rank[x] == rank[y]) rank[y]++; } } bool same(int x, int y){ return find(x) == find(y); } }; int friends[2000]; int main(){ UF uf; int n,k,m; scanf("%d%d",&n,&k); uf.init(n); for(int i = 0; i < k; i++){ int a,b; scanf("%d%d",&a,&b); uf.unite(a-1,b-1); } scanf("%d",&m); for(int i = 0; i < m; i++){ int a,b; scanf("%d%d",&a,&b); if(uf.same(a-1,b-1)){ friends[uf.find(a-1)] = -1e9; } } for(int i = 0; i < n; i++){ friends[uf.find(i)]++; } sort(friends,friends+n); printf("%d\n",friends[n-1]); return 0; }
D.
部分和を求める問題。数列b_iの負の項を0と考えることで、実装が楽になります。
100000増やしておきましたが、mapを使っても良さそうです。
int a[100000],b[200000]; int n,m,mod; int main(){ scanf("%d%d%d",&n,&m,&mod); for(int i = 0; i < n; i++) scanf("%d",a+i); for(int i = 0; i < m; i++) scanf("%d",b+i+100000); int sum = 0,en = n-m+1; for(int i = 0; i < n; i++){ sum -= b[i+100000-en]; sum += b[i+100000]; if(sum<0) sum += mod; sum %= mod; a[i] = (a[i]+sum) % mod; } printf("%d",a[0]); for(int i = 1; i < n; i++) printf(" %d",a[i]); printf("\n"); return 0; }
E.読めない
F.解けない
G.解けない