1.Bear and Poker
题目链接:
http://codeforces.com/problemset/problem/573/A
解题思路:
Any positive integer number can be factorized and written as 2a·3b·5c·7d·....
We can multiply given numbers by 2 and 3 so we can increase a and b for them. So we can make all a and b equal by increasing
them to the same big value (e.g. 100). But we can't change powers of other prime numbers so they must be equal from the
beginning. We can check it by diving all numbers from input by two and by three as many times as possible. Then all of them must
be equal.
Alternative solution is to calculate GCD of given numbers. Answer is "YES" iff we can get each number by multiplying GCD by 2 and 3. Otherwise, some number had different power of prime number other than 2 and 3.
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[100005];
int gcd(int x,int y){
if(y == 0)
return x;
else
return gcd(y,x%y);
}
int main(){
int n;
while(~scanf("%d",&n)){
int tmp,flag = 1;
ll ans;
for(int i = 0;i < n; i++)
scanf("%lld",&a[i]);
for(int i = 1; i < n; i++){
tmp = gcd(a[i-1],a[i]);
ans = (ll)(a[i-1]/tmp)*(a[i]/tmp);
while(ans%2 == 0)
ans /= 2;
while(ans%3 == 0)
ans /= 3;
if(ans != 1){
flag = 0;
break;
}
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
2.Bear and Blocks
题目链接:
http://codeforces.com/problemset/problem/573/B
解题思路:
In one operation the highest block in each tower disappears. So do all blocks above heights of neighbour towers. And all other
blocks remain. It means that in one operation all heights change according to
formula hi = min(hi - 1, hi - 1, hi + 1) where h0 = hn + 1 = 0. By using this formula two times we get height after
two operations: hi = max(0, min(hi - 2, hi - 1 - 1, hi - 2, hi + 1 - 1, hi + 2)) and so on. From now I will omit max(0, ...) part to make it easier
to read.
After k operations we get hi = min(Left, Right) where Left = min(hi - j - (k - j)) = min(hi - j + j - k) for and Right is
defined similarly. hi becomes zero when Left or Right becomes zero. And Left becomes zero when k = min(hi - j + j) — we will find
this value for all i. If you are now lost in this editorial, try to draw some test and analyze my formulas with it.
For each i we are looking for min(hi - j + j). We can iterate over i from left to right keeping some variable best:
best = max(best, h[i]);
best is answer for i;
best++;
We should to the same for Right and take min(Left, Right) for each i. Then final answer is maximum over answers for i.
题目大意:
一些挨着的塔,塔由许多方块构成。每次消除没有四面都有方块围绕的方块,求总共进行多少次消除操作。
算法思想:
对于一个点,它只能被它左边或者右边更新,不存在先被左边更新再被右边更新的情况(实际上如果存在,则最后的更新数也和只被左边和右边更新次数一样)。于是应该想到dp,被左边和右边更新的最小值即为该点被更新次数。然后遍历到开头。
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int dp[maxn];
int main(){
int n;
while(~scanf("%d", &n)){
for(int i = 1 ; i <= n ; i++)
scanf("%d", &dp[i]);
dp[0] = 0;
dp[n + 1] = 0;
for(int i = 1 ; i <= n ; i++)
dp[i] = min(dp[i], dp[i - 1] + 1);
for(int i = n ; i >= 1 ; i--)
dp[i] = min(dp[i], dp[i + 1] + 1);
int ans = 0;
for(int i = 1 ; i <= n ; i++)
ans = max(ans, dp[i]);
printf("%d\n", ans);
}
return 0;
}