Robot Sequence
题目连接:
http://codeforces.com/problemset/problem/626/A
解题思路:
We can simulate Calvin’s path on each substring, and check if he returns to the origin.
Runtime: O(n3)
AC代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
string str;
while(~scanf("%d",&n)){
cin>>str;
int ans = 0,x,y;
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
x = 0;y = 0;
for(int k = i; k <= j; k++){
if(str[k] == 'U')
y++;
if(str[k] == 'D')
y--;
if(str[k] == 'L')
x--;
if(str[k] == 'R')
x++;
}
if(x == 0 && y == 0)
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
Cards
题目连接:
http://codeforces.com/problemset/problem/626/B
解题思路:
Note that if we have exactly one card of each color, we can always make all three options (by symmetry). Thus, if we have at least one of each color, or at least two of each of two colors, we can make all three options. The remaining cases are: if we only have one color, that’s the only possible final card; if we have one of each of two colors, we can only make the third color; if we have at least two of one color and exactly one of a second, we can only make the second or third color (e.g. sample 2).
Runtime: O(1)
AC代码:
#include <bits/stdc++.h>
using namespace std;
int dp[205][205][205];
int solve(int b,int g,int r){
if(b<0 || g<0 || r<0)
return 0;
if(b+g+r == 1){
if(b == 1)
return 1;
else if(g == 1)
return 2;
else
return 4;
}
if(dp[b][g][r] != -1)
return dp[b][g][r];
int ans = 0;
if(b >= 1 && g >= 1)
ans |= solve(b-1,g-1,r+1);
if(g >= 1 && r >= 1)
ans |= solve(b+1,g-1,r-1);
if(b >= 1 && r >= 1)
ans |= solve(b-1,g+1,r-1);
if(b >= 2)
ans |= solve(b-1,g,r);
if(g >= 2)
ans |= solve(b,g-1,r);
if(r >= 2)
ans |= solve(b,g,r-1);
return dp[b][g][r] = ans;
}
int main(){
int n;
string str;
while(~scanf("%d",&n)){
cin>>str;
memset(dp,-1,sizeof(dp));
int cnta = 0,cntb = 0,cntc = 0;
for(int i = 0; i < n; i++){
if(str[i] == 'B')
cnta++;
else if(str[i] == 'G')
cntb++;
else
cntc++;
}
int ans = solve(cnta,cntb,cntc);
string s = "";
if(ans & 1)
s += 'B';
if(ans & 2)
s += 'G';
if(ans & 4)
s += 'R';
printf("%s\n",s.c_str());
}
return 0;
}
Block Towers
题目连接:
http://codeforces.com/problemset/problem/626/C
解题思路:
There are a variety of ways to do this problem. Here is one way: if the answer is X, there must be at least n multiples of 2 below X, at leastm multiples of 3 below X, and at least n + m multiples of 2 or 3 below X. These conditions are actually sufficient, so we need to find the smallest X such that ,
, and
. We can do this with a linear search, or with an explicit formula.
Runtime: O(1)
AC代码:
#include <bits/stdc++.h>
using namespace std;
int n,m;
bool solve(int x){
if(x == -1)
return false;
int ns = x/2,ms = x/3,ss = x/6;
int nn = n,mm = m;
nn -= ns-ss;
mm -= ms-ss;
nn = max(0,nn);
mm = max(0,mm);
return ss >= nn+mm;
}
int main(){
while(~scanf("%d%d",&n,&m)){
int l = 0, r = 10000000;
while(l <= r){
int mid = (l+r)/2;
if(solve(mid))
r = mid-1;
else
l = mid+1;
}
printf("%d\n",l);
}
return 0;
}
Jerry's Protest
题目连接:
http://codeforces.com/problemset/problem/626/D
解题思路:
We do this algorithm in two phases: first, we compute the probability distribution of the difference between the winner and loser of each round. This takes O(n2) time. Then, we can iterate over the 2 differences which Andrew wins by and compute the probability that Jerry has a greater total using with suffix sums.
Runtime: O(n2 + amax2)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[2005], cnt[5010];
long long gre[5010];
int main(){
int n;
while(~scanf("%d", &n)){
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
sort(a,a+n);
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
int x = a[j] - a[i];
cnt[x]++;
}
}
ll sum = 0;
for(int i = 5005; i >= 0; i--){
gre[i] = sum;
sum += cnt[i];
}
double ans = 0;
for(int i = 0; i <= 5005; i++){
for(int j = 0; j <= 5005; j++){
if(i + j >= 5005)
continue;
ans += (long double)cnt[i] * cnt[j] * gre[i + j];
}
}
for(int i = 0; i < 3; i++)
ans /= n * (n - 1)/2;
printf("%.10lf\n",ans);
}
return 0;
}