@lawk97
        
        2017-04-19T16:24:02.000000Z
        字数 4688
        阅读 1286
    STL
POJ - 2010 
 - 题意 
奶牛大学招生啦。有C只奶牛申请,会录取N只(N为奇数)。每只奶牛上学需要不同数额的赞助,而学校可以用于赞助奶牛学生的总经费为F。在学校经费的限制下,要使录取的N只奶牛TA们的成绩中位数尽可能高,求出这中位数的可能最大值。 
 - 思路 
首先将奶牛按成绩高低排序。 
因为要录取N只奶牛,所以成绩是中位数的奶牛在所有奶牛中的次序必然在[N/2+1,C-N/2]之间取值。在TA前面的奶牛和在TA后面的奶牛,各录取需赞助少的N/2只。如果TA所需的赞助加上其他奶牛需要的赞助之和,小于等于总经费F,则说明这只奶牛的成绩可以作为中位数。 
在可作为“中间奶牛”的奶牛中,取成绩的最高的那个。 
使用优先队列,便于找到当前奶牛前面和后面的,需赞助少的N/2只。
#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>#include <cstring>#include <string>#include <queue>using namespace std;int n,c,f;int ans=-1;int lef[100005],rig[100005];struct student{int score,cost;}cow[100005];priority_queue<int>q1,q2;int cmp(student a,student b){return a.score<b.score;}int main(){scanf("%d%d%d",&n,&c,&f);for(int i=0;i<c;i++)scanf("%d%d",&cow[i].score,&cow[i].cost);sort(cow, cow+c, cmp);int l=n/2,r=c-n/2-1;int sum1=0,sum2=0;for(int i=0;i<l;i++){sum1+=cow[i].cost;q1.push(cow[i].cost);}for(int i=l;i<=r;i++){lef[i]=sum1;q1.push(cow[i].cost);int top=q1.top();sum1+=cow[i].cost-top;q1.pop();}for(int i=c-1;i>r;i--){sum2+=cow[i].cost;q2.push(cow[i].cost);}for(int i=r;i>=l;i--){rig[i]=sum2;q2.push(cow[i].cost);int top=q2.top();sum2+=cow[i].cost-top;q2.pop();}for(int i=r;i>=l;i--){if(cow[i].cost+lef[i]+rig[i]<=f){ans=cow[i].score;break;}}printf("%d\n",ans);return 0;}
CodeForces - 732E 
 - 题意 
有n台电脑,m个插座,若电脑与插座电压相同,则可以将其连接并正常使用该电脑。也可将插座与适配器相连,转化为一个电压为原值一半(向上取整)的新插座。已知适配器数量充足。 
求最多有多少台电脑可用,若有多种方案,以适配器使用量最少的一种为优。 
 - 思路 
电源的电压只能降低,不能升高。 
若一个电源的电压,既可以适配一个需电压大的电脑,又可以适配一个需电压小的电脑,那么使他适配需电压大的电脑,既可以保证尽可能多的电脑被供能(贪心),又可以减少适配器的使用。 
所需电压比各种电源的供电压最大值还大的电脑,一定不能使用。 
所供电压比各种电脑的需电压最大值还大的电源,如果不用适配器,肯定不可以接任何电脑。 
因此,可将电源和电脑分别按电压从大到小排序,进行比对。因为电源电压可以变化,且我们需要尽可能控制适配器的使用,所以使用优先队列来放置电源。放置电源的优先队列中,电压高的优先,电压相等的电源所用适配器少的优先。 
具体思路如下程序。 
 - 代码
#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <map>#include <stack>#include <queue>using namespace std;int n,m,use=0,sum=0;struct sw{int id,vol,num;friend bool operator <(sw a ,sw b){//优先队列默认队头元素最大if(a.vol!=b.vol)return a.vol<b.vol;return a.num>b.num;}}s[200005];struct cu{int id,vol,ans;}c[200005];priority_queue<sw> pq;int cmp_id(cu a,cu b){return a.id<b.id;}int cmp_v(cu a ,cu b){return a.vol>b.vol;}int main(){scanf("%d%d",&n,&m);for(int i=0;i<n;i++){scanf("%d",&c[i].vol);c[i].id=i+1;c[i].ans=0;}for(int i=0;i<m;i++){sw si;scanf("%d",&s[i].vol);s[i].id=i+1;s[i].num=0;pq.push(s[i]);}sort(c,c+n,cmp_v);for(int i=0;i<n;i++){if (pq.empty()){break;}sw f=pq.top();if(f.vol==c[i].vol){pq.pop();c[i].ans=f.id;s[f.id-1]=f;sum+=f.num;use++;}else if(f.vol>c[i].vol){pq.pop();f.num++;f.vol=ceil(1.0*f.vol/2);pq.push(f);i--;}}sort(c,c+n,cmp_id);printf("%d %d\n",use,sum );for(int i=0;i<m;i++){if (i!=0){printf(" ");}printf("%d",s[i].num );}printf("\n");for(int i=0;i<n;i++){if (i!=0){printf(" ");}printf("%d",c[i].ans );}printf("\n");return 0;}
#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <map>#include <stack>#include <queue>using namespace std;#define INF 1000005int n,dir,num,minx,now,ans;int used[155],sl[155],gra[155][155];string be,st;map<string,int> m;int main(){while(~scanf("%d",&n)&&n!=-1){cin>>be>>st;num=1;minx=INF;ans=INF;m.clear();memset(sl,0,sizeof(sl));memset(used,0,sizeof(used));for (int i = 0; i < 155; ++i){for (int j = 0; j < 155; ++j){gra[i][j]=INF;if (i==j){gra[i][j]=0;}}}m[be]=num++;m[st]=num++;if (be==st){ans=0;/*must do it to stop the program,because there are a wrong m[be]=2*/}for(int i=0;i<n;i++){cin>>be>>st;scanf("%d",&dir);//opertion 'cin' spend too much timeif(m[be]==0){m[be]=num++;}if(m[st]==0){m[st]=num++;}gra[m[be]][m[st]]=dir;gra[m[st]][m[be]]=dir;//no direction}if (ans==0){printf("%d\n",ans );continue;}for(int i=1;i<num;i++){sl[i]=gra[1][i];}used[1]=1;now=1;//now must have initial value,if the begin point can't connect to others,for (int i = 2; i < num; ++i){minx=INF;for(int j=1;j<num;j++){if (!used[j]&&sl[j]<minx){now=j;minx=sl[j];}}used[now]=1;for (int j = 1; j < num; ++j){if (!used[j]&&sl[now]+gra[now][j]<sl[j]){sl[j]=sl[now]+gra[now][j];}}}if (sl[2]<INF){printf("%d\n",sl[2] );}else{printf("-1\n");}}return 0;}
#include <cstdio>#include <iostream>#include <algorithm>#include <cmath>#include <cstring>#include <map>using namespace std;int n,l,r,num,flag;int anl[300005],anr[300005];map<int,int> p;int main(){scanf("%d",&n);l=1;r=2;num=0;flag=0;for(int i=1;i<=n;i++){int now;scanf("%d",&now);if (!flag&&p[now]>0) {r=i;flag=1;}if(flag&&p[now]>r){anl[num]=l;anr[num]=r;num++;l=r+1;r=i;}if (i==n) {anl[num]=l;anr[num]=n;num++;}p[now]=i;}if (flag) {printf("%d\n",num);for (int i=0; i<num; i++) {printf("%d %d\n",anl[i],anr[i]);}}else{printf("-1\n");}}