POJ 2454 Jersey Politics
题目大意:
给出3*k个数,将它们分成三分,每份k个数,要求至少有两份之和大于500*k。
解题思路:
随机化,对于这道题来说这是个好想法~
将所有数从大到小排序后将前2*k个数再随机调整直到满足条件。
下面是代码:
#include <set> #include <map> #include <queue> #include <math.h> #include <vector> #include <string> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #define eps 1e-8 #define pi acos(-1.0) #define inf 107374182 #define inf64 1152921504606846976 #define lc l,m,tr<<1 #define rc m + 1,r,tr<<1|1 #define iabs(x) ((x) > 0 ? (x) : -(x)) #define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE)) #define clearall(A, X) memset(A, X, sizeof(A)) #define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE)) #define memcopyall(A, X) memcpy(A , X ,sizeof(X)) #define max( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define min( x, y ) ( ((x) < (y)) ? (x) : (y) ) using namespace std; struct node { int nu,t; }num[200],num1[100],num2[100],temp; bool cmp(node a,node b) { return a.nu>b.nu; } int main() { int k,sum1=0,sum2=0,rd1,rd2; scanf("%d",&k); for(int i=0;i<3*k;i++) { scanf("%d",&num[i].nu); num[i].t=i; } sort(num,num+(3*k),cmp); for(int i=0;i<2*k;i+=2) { //printf("%d\n",num[i].t+1); num1[i/2]=num[i]; sum1+=num[i].nu; } for(int i=1;i<2*k;i+=2) { //printf("%d\n",num[i].t+1); num2[i/2]=num[i]; sum2+=num[i].nu; } while(sum1<=500*k||sum2<=500*k) { rd1=rand()%k; rd2=rand()%k; sum1=sum1-num1[rd1].nu+num2[rd2].nu; sum2=sum2-num2[rd2].nu+num1[rd1].nu; temp=num1[rd1]; num1[rd1]=num2[rd2]; num2[rd2]=temp; } for(int i=0;i<k;i++) { printf("%d\n",num1[i].t+1); } for(int i=0;i<k;i++) { printf("%d\n",num2[i].t+1); } for(int i=2*k;i<3*k;i++) { printf("%d\n",num[i].t+1); } return 0; }