Codeforces Round #113 (Div. 2)

http://codeforces.com/contest/166

这次rating终于涨了。。呵呵。。。

A:水题,不过看了好长时间才看懂,才开始我的下标是从0开始的k忘减一了,结果贡献了一次wa。。。。先按解题数和罚时排序,然后统计相同名次的人的个数。。

C:大部分的时间都花在了调这个程序上了,唉。。不过到了最后1Y呵呵。。。

题意:给你随便的n个数,以及要求得到的中位数x.让你随便添加任意数,是的添加后的序列的中位数是x。求最少添加个数。。。

思路:首先检查x是否存在序列中,如果不存在则添加x然后从小到大排序,求出中位数zh。然后将求的中位数zh与x比较,如果中位数zh>x则在左边添加比中位数x小的数,使中位数zh左移直到遇见x,当zh<x时同理在右边添加比x大的数,使zh右移直到遇到x。注意对于奇数偶数个序列的移动有的要添加两个数才能移动,有的只需添加一个数就能移动。。

View Code
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 505
using namespace std;

int n,x;
int a[maxn];
int cmp(int a,int b)
{
return a < b;
}
int main()
{
int zh,i,ct;
while (~scanf("%d%d",&n,&x))
{
ct = 0;
bool flag = false;
for (i = 1; i <= n; ++i)
{
scanf("%d",&a[i]);
if (a[i] == x) flag = true;//判断x是否在序列中存在
}
if (!flag)//不存在就添加
{
a[n + 1] = x;
n++;
}
sort(a+1,a + n + 1,cmp);
int pos = (n + 1)/2;
//printf(">>%d %d\n",n,a[pos]);
zh = a[pos];//找到序列的中位数
while (zh != x)
{
if (n % 2 == 0)//如果n为偶数
{
if (zh > x)
{
ct += 2; n += 2;//在左边添加两个比x小的数才能使zh移动
zh = a[--pos];
}
else if (zh < x)//在右边添加1个比x大的数才能使zh移动
{
ct++; n++;
zh = a[++pos];
}
}
else
{
if (zh < x)//在右边添加两个比x大的数才能使zh移动
{
ct += 2; n += 2;
zh = a[++pos];
}
else if (zh > x)//在左边添加一个比x小的数才能使zh移动
{
ct++; n++;
zh = a[--pos];
}
}
}
if (!flag)
printf("%d\n",ct + 1);
else
printf("%d\n",ct);
}
}


E:才读题的时候感觉好像是找规律的题目,思考了一段时间没思路,果断放弃了,今天看了牛人的代码,果然好犀利。。。

dp[i][D]走i步到达D点的步数。。。dp[i + 1][d] = dp[i + 1][d] + dp[i][A] + dp[i][B] + dp[i][C];

View Code
#include <cstdio>
#include <iostream>
#define A 0
#define B 1
#define C 2
#define D 3
using namespace std;

const int mod = 1000000007;

int dp[10000007][5];

int main()
{
int n;
cin>>n;
dp[0][D] = 1;
for (int i = 0; i < n; ++i)
{
dp[i + 1][A] += dp[i][D];
dp[i + 1][B] += dp[i][D];
dp[i + 1][C] += dp[i][D];
dp[i + 1][A] %= mod;
dp[i + 1][B] %= mod;
dp[i + 1][C] %= mod;

dp[i + 1][D] += dp[i][A];
dp[i + 1][B] += dp[i][A];
dp[i + 1][C] += dp[i][A];
dp[i + 1][D] %= mod;
dp[i + 1][B] %= mod;
dp[i + 1][C] %= mod;

dp[i + 1][A] += dp[i][B];
dp[i + 1][D] += dp[i][B];
dp[i + 1][C] += dp[i][B];
dp[i + 1][A] %= mod;
dp[i + 1][D] %= mod;
dp[i + 1][C] %= mod;

dp[i + 1][A] += dp[i][C];
dp[i + 1][B] += dp[i][C];
dp[i + 1][D] += dp[i][C];
dp[i + 1][A] %= mod;
dp[i + 1][B] %= mod;
dp[i + 1][D] %= mod;
}
printf("%d\n",dp[n][D]);
return 0;
}

有规律 令f[i]表示走i步回到起点的方法数,g[i]表示走i步到A/B/C的方法数。那么f[i]+g[i]=3^i以及f[i]=g[i-1],解得f[i]=3^(i-1)-f[i-1]。  本人参考牛人。。



posted @ 2012-03-24 10:50  E_star  阅读(231)  评论(0编辑  收藏  举报