The 10th Zhejiang Provincial Collegiate
Programming Contest
Solution
Problem A: Applications
Problem B: BreakStandard Weight
Problem C: CalculatePrime S
Problem D: Densityof Power Network
Problem E: EggPainting
Problem F: Friends
Problem G: Give MeYour Hand
Problem H: Hardto Play
Problem I: In7-bit
Problem J: JavaBeans
Problem K: KindergartenElection
June 3rd,2013 by chlxyd
ZOJ 3705~3715
Problem A: Applications
给出一个积分方式,问每个人最后的分数并排序。
Solution
Tag:模拟
按照题目做就可以了,不是很难。
/*
* Author: chlxyd
* Created Time: 2013/5/29 15:38:37
* File Name: A.CPP
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-11);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
int sgn(double x) {
return (x > eps) - (x < -eps);
}
struct node {
string name;
double val;
node (string _name = "", double _val = 0.0) : name(_name), val(_val){
}
bool operator < (const node &b) const {
if (sgn(val - b.val) != 0) return val > b.val;
else return name < b.name;
}
};
int n, m;
set<int> mao, S, pr;
map<string, int> team;
vector<node> peo;
node getPon() {
string name, tm, sex;
vector<int> c;
double res = 0;
int pn, cn;
cin >> name >> tm >> sex >> pn >> cn;
//cout << name << " " << tm << " " << sex << endl;
if (sex[0] == 'F') res += 33;
if (team.count(tm) == 1) {
res += team[tm];
}
rep (i, pn) {
int x;
scanf("%d", &x);
if (mao.find(x) != mao.end()) {
res += 2.5;
}
else if (S.find(x) != S.end()) {
res += 1.5;
}
else if (pr.find(x) != pr.end()) {
res += 1;
}
else {
res += 0.3;
}
}
rep (i, cn) {
int x;
scanf("%d", &x);
c.push_back(x);
}
sort(c.begin(), c.end());
reverse(c.begin(), c.end());
if (sz(c) >= 3) {
res += max(0.0, (c[2] - 1200) / 100.0) * 1.5;
}
return node(name, res);
}
void init() {
scanf("%d%d", &n, &m);
int mn, sn, tn;
mao.clear();
S.clear();
scanf("%d", &mn);
rep (i, mn) {
int x;
scanf("%d", &x);
mao.insert(x);
}
scanf("%d", &sn);
rep (i, sn) {
int x;
scanf("%d", &x);
S.insert(x);
}
scanf("%d", &tn);
team.clear();
rep (i, tn) {
string name;
int pr;
cin >> name >> pr;
if (pr == 1) pr = 36;
else if (pr == 2) pr = 27;
else if (pr == 3) pr = 18;
else pr = 0;
team[name] = pr;
}
peo.clear();
rep (i, n) {
node res;
res = getPon();
peo.push_back(res);
}
}
int v[20000 + 10];
void getPr() {
int lim = 20000 + 10;
memset(v, 0, sizeof(v));
pr.clear();
for (int i = 2; i < lim; i++) {
if (!v[i]) {
pr.insert(i);
for (int j = i + i; j < lim; j += i) {
v[j] = 1;
}
}
}
}
void gao() {
sort(peo.begin(), peo.end());
rep (i, m) {
cout << peo[i].name;
printf(" %.3f\n", peo[i].val);
}
}
int main(){
int T;
getPr();
scanf("%d", &T) ;
while (T--) {
init();
gao();
}
return 0;
}
Problem B: BreakStandard Weight
略
Solution
Tag:暴力
略
/*
* Author: chlxyd
* Created Time: 2013/5/29 13:53:33
* File Name: B.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
int gao(int xx, int yy) {
int x, y, z;
int res = 0;
repf (i, 1, xx - 1) {
vector<int> a;
x = i;
z = xx - i;
y = yy;
repf (ii, -1, 1)
repf (jj, -1, 1)
repf (kk, -1, 1) {
a.push_back(ii * x + jj * y + kk * z);
}
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
int h = 0;
rep (j, sz(a))
if (a[j] > 0) {
h = sz(a) - j;
break;
}
res = max(h, res);
}
return res;
}
int main(){
int T;
scanf("%d", &T);
while (T--) {
int x, y;
scanf("%d%d", &x, &y);
int res = 0;
res = max(res, gao(x, y));
res = max(res, gao(y, x));
printf("%d\n", res);
}
return 0;
}
Problem C: CalculatePrime S
S[n]是1到n中不包含连续数的子集的个数,如果s[n]与s[1]~s[n-1]均互斥,那么定义s[n]为素数,问最小的s[n]使s[n]是x的倍数,且s[n]不小于第k个素数。
Solution
Tag:数论
首先可以看出s[n]是斐波拉契数列,根据斐波拉契数列的性质,s[a]为质数,那么a为质数,即,找到第k个质数做下标,f[k]即是下界,那么对于x,斐波拉契数列mod x的结果一定构成一个循环,算出循环里有多少个0,即有多少数能被x整除,即可以通过循环节找到答案的下标位置,设为g,现在就是求(f[g]/x)%M的值。可以也按照循环节的方式来做,不过会T,有一个性质是a / b % m = a % (m * b) / b , 这样就可以先用矩阵乘法算出上面的然后再除下面了。
/*
* Author: xioumu
* Created Time: 2013/5/29 17:47:57
* File Name: C.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (lint i = 0; i < (n); ++i)
#define repf(i, a, b) for (lint i = (a); i <= (b); ++i)
#define repd(i, a, b) for (lint i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
const lint maxa = 3;
const lint lim = 20000000;
lint mod;
vector<lint> pri;
bool v[lim];
lint K, X, M;
struct matrix {
lint ar[maxa][maxa];
lint n, m ; // n * m; 0 ~ n - 1, 0 ~ m - 1;
matrix(int _n = 0, int _m = 0) : n(_n), m(_m) {
memset(ar, 0, sizeof(ar));
}
void clear() {
rep (i, n)
rep (j, m)
ar[i][j] = 0;
}
void set_one() {
rep (i, n)
rep (j, m)
ar[i][j] = 0;
rep (i, min(n, m))
ar[i][i] = 1;
}
void output() {
printf("%lld %lld\n", n, m);
rep(i, n) {
rep(j, m)
printf("%lld ", ar[i][j]);
printf("\n");
}
printf("\n");
}
};
matrix operator * (const matrix &a, const matrix &b) {
matrix c;
if(a.m != b.n) printf("a.m != b.n\n");
c.clear();
c.n = a.n;
c.m = b.m;
rep (i, a.n)
rep (j, b.m)
rep (k, a.m) {
c.ar[i][j] += a.ar[i][k] * b.ar[k][j]; //mod
c.ar[i][j] %= mod;
}
return c;
}
void getPr() {
pri.clear();
memset(v, 0, sizeof(v));
for (lint i = 2; i < lim; i++) {
if (!v[i]) {
pri.push_back(i);
}
else if (i == 4)
pri.push_back(2);
for (lint j = 0; (lint)i * pri[j] < lim; j++) {
v[i * pri[j]] = true;
if (i % pri[j] == 0) {
break;
}
}
}
pri[2] = 4;
//printf("=%d\n", pri[1]);
}
matrix pow(matrix a, lint b) {
matrix res;
res.n = res.m = 2;
res.set_one();
//printf("b: %lld\n", b);
while (b != 0) {
//cout << "BB: " << b << endl;
if (b & 1) {
res = a * res;
}
a = a * a;
b >>= 1;
}
//res.output();
return res;
}
lint gao(lint be) {
//printf("be : %d\n", be);
matrix a, p;
p.clear();
p.n = p.m = 2;
p.ar[0][0] = p.ar[0][1] = p.ar[1][0] = 1;
p.ar[1][1] = 0;
p = pow(p, be - 1);
//p.output();
a.clear();
a.n = 2, a.m = 1;
a.ar[0][0] = 1;
a.ar[1][0] = 1;
a = p * a;
lint now1 = a.ar[0][0], now2 = a.ar[1][0];
//printf("%lld %lld\n", now1, now2);
rep (i, 20000) {
//printf("=%lld\n", now1);
if (now2 % X == 0) return now2 / X;
lint now3 = (now1 + now2) % mod;
now2 = now1;
now1 = now3;
//printf("%lld\n", now1);
}
return -1;
}
int main(){
getPr();
lint T;
scanf("%lld", &T);
while (T--) {
scanf("%lld%lld%lld", &K, &X, &M);
mod = X * M;
//printf("%lld\n", pri[K]);
lint ans = gao(pri[K]); //题目说 not less than the Kth, 觉得应该是K - 1, 也许标程错了?
printf("%lld\n", ans % M);
}
return 0;
}
Problem D: Densityof Power Network
略
Solution
Tag:图论
略
/*
* Author: chlxyd
* Created Time: 2013/5/29 14:07:51
* File Name: D.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
const int maxn = 507;
bool a[maxn][maxn];
int x[maxn], y[maxn];
int n, m;
int main(){
int T;
scanf("%d", &T);
memset(a, 0, sizeof(a));
while (T--) {
scanf("%d%d", &n, &m);
int ans = 0;
rep (i, m) {
scanf("%d", &x[i]);
}
rep (i, m) {
scanf("%d", &y[i]);
}
rep (i, m) {
if (!a[x[i]][y[i]])
ans++;
a[x[i]][y[i]] = a[y[i]][x[i]] = true;
}
rep (i, m)
a[x[i]][y[i]] = a[y[i]][x[i]] = false;
printf("%.3f\n", ans * 1.0 / n);
}
return 0;
}
Problem E: EggPainting
Unknown
Solution
Tag:unknown
Unknown
Problem F: Friends
给很多人和朋友关系,两个人如果公共朋友大于等于k那么他们会变成朋友,问最后会新增多少对朋友关系。
Solution
Tag:图论
可以用类似spfa的方法对于每一条新增的边计算由它可以生成的新边,加入队列中。复杂度O(n3)。
/*
* Author: chlxyd
* Created Time: 2013/5/29 14:14:47
* File Name: F.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
int T ;
int n , m , K ;
int f[200][200] ;
int num[200][200] ;
queue<pair<int,int> > q ;
int main(){
scanf("%d" , &T ) ;
repf( t , 1 , T ) {
while (!q.empty()) q.pop() ;
clr(num) ; clr(f) ;
scanf("%d %d %d" , &n , &m , &K ) ;
repf( i , 1 , m ) {
int a , b ;
scanf("%d %d" , &a , &b ) ;
a ++ ; b ++ ;
f[a][b] = f[b][a] = true ;
}
repf( k , 1 , n )
repf( i , 1 , n )
repf( j , i + 1 , n ) {
if ( f[i][k] && f[k][j] ) {
num[i][j] ++ ; num[j][i] ++ ;
}
}
repf( i , 1 , n )
repf( j , i + 1 , n ) {
if ( num[i][j] >= K && !f[i][j] ) {
f[i][j] = f[j][i] = true ;
q.push( make_pair(i,j) ) ;
}
}
int ans = 0 ;
while ( !q.empty() ) {
int a = q.front().first , b = q.front().second ;
//cout<<a<<" "<<b<<endl;
q.pop() ; ans ++ ;
repf( i , 1 , n ) {
if ( f[i][a] ) {
if ( i == b ) continue ;
num[i][b] ++ ; num[b][i] ++ ;
if ( num[i][b] >= K && !f[i][b] ) {
f[i][b] = true ; f[b][i] = true ;
q.push(make_pair(i,b)) ;
}
}
}
swap( a , b ) ;
repf( i , 1 , n ) {
if ( f[i][a] ) {
if ( i == b ) continue ;
num[i][b] ++ ; num[b][i] ++ ;
if ( num[i][b] >= K && !f[i][b] ) {
f[i][b] = true ; f[b][i] = true ;
q.push(make_pair(i,b)) ;
}
}
}
}
printf("%d\n" , ans ) ;
}
}
Problem G: GiveMe Your Hand
寝室最开始是空的,寝室有n个人,其中A和B比较特殊,其余是酱油,A如果在寝室呆着超过了T分钟,那么A就开始打游戏,这时如果B在里面,那么A就失去一只玩具手,然后又可以再呆T分钟,A有M只玩具手,给很多时间,每个时间发生一个事件,事件包括一个人进或者一个人出,进或者出或者谁进谁出都是随机的,问A最后失去的玩具手的期望。
Solution
Tag:DP
状态:f[i][S][T][m]表示在事件i,A和B是否在寝室的状态为S(0~3),A已经在寝室呆了T分钟,还剩m只玩具手的概率,转移见代码。
/*
* Author: chlxyd
* Created Time: 2013/5/29 16:45:55
* File Name: G.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
int T , num , n , m ;
double p[110][4][110][110] ;
//int flag[110][4][110][110] ;
int t1[200] ;
int minu( int a , int b ) {
if ( a > b ) return a - b ;
return 0 ;
}
int main(){
int T_T ;
scanf("%d" , &T_T ) ;
//freopen("G.out","w",stdout);
repf( tt , 1 , T_T ) {
scanf("%d %d %d %d" , &T , &num , &m , &n ) ;
repf( i , 0 , num + 1 )
repf( j , 0 , 3 )
repf( k , 0 , T )
repf( l , 0 , m )
p[i][j][k][l] = 0 ;
clr(t1) ;
p[0][0][0][m] = 1.0 ;
repf( i , 1 , num + 1 ) {
bool flag = true ;
if ( i != num + 1 )
scanf("%d" , &t1[i] ) ;
else {
flag = false ;
t1[i] = 1440 ;
}
if ( t1[i-1] == 1440 ) continue ;
int t = t1[i] - t1[i-1] ;
//cout<<"task"<<i<<endl;
//cout<<t<<endl;
double now = 0 ;
//00
repf( j , 0 , m ) {
now = p[i-1][0][0][j] ;
p[i][1][0][j] += now / n ;
p[i][2][0][j] += now / n ;
p[i][0][0][j] += now * ( n - 2 ) / n ;
}
//01
repf( j , 0 , m ) {
now = p[i-1][1][0][j] ;
p[i][3][0][j] += now / n ;
p[i][1][0][j] += now * ( n - 2 ) / n ;
p[i][0][0][j] += now / n ;
}
//10
repf( j , 0 , T )
repf( k , 0 , m ) {
now = p[i-1][2][j][k] ;
if ( flag )
p[i][3][(j+t>=T)?0:(j+t)][minu(k,j+t>=T)] += now / n ;
else p[i][2][min(T,j+t)][k] += now / n ;
p[i][0][0][k] += now / n ;
p[i][2][min(T,j+t)][k] += now * ( n - 2 ) / n ;
}
//11
repf( j , 0 , T )
repf( k , 0 , m ) {
now = p[i-1][3][j][k] ;
int nt = ( j + t ) % T ;
int nk = minu( k , ( j + t ) / T ) ;
p[i][1][0][nk] += now / n ;
p[i][2][nt][nk] += now / n ;
p[i][3][nt][nk] += now * ( n - 2 ) / n ;
}
if ( t1[i] == 1440 ) {
num = i ;
break ;
}
}
//cout<<p[3][3][0][m-1]<<endl;
double ans = 0 ;
repf( i , 0 , 3 )
repf( j , 0 , T )
repf( k , 0 , m )
ans += p[num][i][j][k] * k ;
printf("%.6lf\n" , ans ) ;
}
}
Problem H: Hardto Play
略
Solution
Tag:贪心
略
/*
* Author: chlxyd
* Created Time: 2013/5/29 13:44:36
* File Name: H.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (long long i = 0; i < (n); ++i)
#define repf(i, a, b) for (long long i = (a); i <= (b); ++i)
#define repd(i, a, b) for (long long i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
long long cal( long long p , long long n , long long val ) {
return val * p * 2 * n + val * ( n - 1 ) * n ;
}
long long T ;
long long a , b , c ;
int main(){
scanf("%lld" , &T ) ;
repf( t , 1 , T ) {
scanf("%lld %lld %lld" , &a , &b , &c ) ;
long long have = a * 300 + b * 100 + c * 50 ;
//cout<<cal(a+b,c,50)<<endl;
long long minn = cal( 0 , a , 300 ) + cal( a , b , 100 ) + cal( a + b , c , 50 ) ;
long long maxx = cal( 0 , c , 50 ) + cal( c , b , 100 ) + cal( b + c , a , 300 ) ;
printf("%lld %lld\n" , minn + have , maxx + have ) ;
}
}
Problem I: In7-bit
给出一种加密方法,按照所给方法对一段文本加密。
Solution
Tag:模拟
按照题目要求做即可。
/*
* Author: chlxyd
* Created Time: 2013/5/29 14:39:59
* File Name: I.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
const int maxn = 3000000 + 100;
char s[maxn];
vector<int> a;
void myput(int w) {
a.clear();
while (w != 0) {
a.push_back(w % 2);
w >>= 1;
//printf("%d\n", a[sz(a) - 1]);
}
if (sz(a) == 0)
a.push_back(0);
for (int i = 0; i < sz(a); i += 7) {
int res = 0;
if (i + 7 >= sz(a)) {
res = 0;
}
else res = 1;
repd (j, min(i + 6, sz(a) - 1), i) {
res = res * 2 + a[j];
}
printf("%02X", res);
}
}
int main(){
int T;
//freopen("I.out", "w", stdout);
//printf("%02X", 15);
scanf("%d", &T);
getchar();
while (T--) {
gets(s);
int len = strlen(s);
myput(len);
rep (i, len) {
printf("%02X", s[i]);
}
printf("\n");
}
return 0;
}
Problem J: JavaBeans
略
Solution
Tag:略
略
/*
* Author: chlxyd
* Created Time: 2013/5/29 13:36:41
* File Name: J.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
int T , n , m ;
int a[400] , s[400] ;
int main(){
scanf("%d" , &T ) ;
repf( t , 1 , T ) {
scanf("%d %d" , &n , &m ) ;
repf( i , 1 , n ) scanf("%d" , &a[i] ) ;
repf( i , n + 1 , n + n ) a[i] = a[i-n] ;
repf( i , 1 , n + n ) s[i] = s[i-1] + a[i] ;
int ans = 0 ;
repf( i , n + 1 , n + n ) ans = max( ans , s[i] - s[i-m] ) ;
printf("%d\n" , ans ) ;
}
}
Problem K: KindergartenElection
有n个人,每个人都有一票,现在已知每个人的票会投给谁(不会投给自己),收买一个人需要一定的代价,现在问1需要最少多少钱去收买人,可以让他的票数比其他所有人都多。
Solution
Tag:枚举
枚举1胜利时的票数,那么这时胜利的最小费用是可以通过贪心求解的,所有的结果取一个最小值就可以了。
/*
* Author: chlxyd
* Created Time: 2013/5/29 15:03:54
* File Name: k.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
queue<int> p[110] , tmp[110] , allh ;
vector<int> v[110] , all ;
int f[110] , c[110] ;
int n ;
int T ;
int solve( int num ) {
int ret = 0 ;
while ( !allh.empty() ) allh.pop() ;
all.clear();
bool flag = true ;
repf( i , 2 , n ) {
while ( p[i].size() >= num ) {
ret += p[i].front() ;
p[1].push(p[i].front()) ;
p[i].pop() ;
}
if ( p[i].size() != num - 1 ) flag = false ;
while ( !p[i].empty() ) {
all.push_back(p[i].front());
p[i].pop() ;
}
}
//cout<<ret<<endl;
//cout<<all.size()<<endl;
sort(all.begin(),all.end());
rep( i , all.size() ) allh.push(all[i]) ;
while ( p[1].size() < num ) {
flag = false ;
ret += allh.front() ;
p[1].push(allh.front()) ;
allh.pop() ;
}
if ( p[1].size() > num ) flag = false ;
if ( flag ) ret += allh.front() ;
return ret ;
}
int main(){
scanf("%d" , &T ) ;
repf( t , 1 , T ) {
scanf("%d" , &n ) ;
repf( i , 1 , n ) {
v[i].clear() ;
while ( !p[i].empty() ) p[i].pop() ;
}
repf( i , 2 , n )
scanf("%d" , &f[i] ) ;
repf( i , 2 , n )
scanf("%d" , &c[i] ) ;
repf( i , 2 , n )
v[f[i]].push_back(c[i]) ;
repf( i , 1 , n ) sort(v[i].begin(),v[i].end());
repf( i , 1 , n )
rep( j , v[i].size() )
p[i].push(v[i][j]) ;
int ans = 100000000 ;
repd( i , n-1 , 2 ) {
repf( j , 1 , n ) tmp[j] = p[j] ;
//cout<<i<<" "<<solve(i)<<endl;
ans = min( ans , solve( i ) );
repf( j , 1 , n ) p[j] = tmp[j] ;
}
printf("%d\n" , ans ) ;
}
}