泰山挑夫1

来源:互联网 发布:淘宝商家后台 编辑:程序博客网 时间:2024/05/17 07:38
A - Watermelon水题:将一个K千克的西瓜分成2份,每一份都是偶数的可能性。只要注意2这个特殊的点即可。   B - Before an Exam题意:Peter还有几天就考试了,他父母给他安排了一个时间表,第i天最多复习Maxi个小时,最少复习Mini个小时,Peter只记得他一用复习了Sum个小时,是否能够满足父母给他的安排!思路:求出最少时间和s1、最大时间和s2,如果Sum[s1,s2]之间就一定可以满足条件。第i天最多复习Maxi天,最少Mini天,所以枚举第i天的复习时间j,只要总时间Sum-j>s1-Mini&&Sum-j<s2-Maxi即可。递归的分析下去即可得到结果。 
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 50+5;const int MAX = 2147483647;int prime [25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};int MinT[N],MaxT[N];int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);//    srand((unsigned)time(NULL));    int d,s,s1,s2;    while(scanf("%d %d",&d,&s)!=EOF)    {        s1 = 0,s2 = 0;        for(int i=1;i<=d;i++)        {            scanf("%d %d",&MinT[i],&MaxT[i]);            s1 += MinT[i];            s2 += MaxT[i];        }        if(s>s2||s<s1)        {            printf("NO\n");        }        else        {            printf("YES\n");            int i,j;            for(i=1;i<d;i++)            {                s1 -= MinT[i];                s2 -= MaxT[i];                for(j=MinT[i];j<=MaxT[i];++j)                {                    if(s-j<=s2&&s-j>=s1)break;                }                s -= j;                printf("%d ",j);            }printf("%d\n",s);        }    }}

 
C- Registration system题意:注册系统中的用户名问题,如果用户名未出现过则可用,否则在用户名末尾加上用户名出现的次序。思路:STL中的map的简单应用  Mysterious Present题意:1个明信片,n个信封,长宽分别为hw,组成一个链A={a1,a2,a3...an},其中第i个信封的长宽分别大于第i-1个信封的长宽,链的长度最大为多少,和链中每个信封在输入数据中的位置。思路:按wh排序后,求一下最长上升子序列 
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 5000+5;const int MAX = 2147483647;int prime [25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};int ans[N],dp[N],pre[N];struct enve{    int w,h;    int num;}enves[N];bool cmp(const enve& a,const enve& b){    if(a.w == b.w)        return a.h<b.h;    else return a.w<b.w;}int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);//    srand((unsigned)time(NULL));    int n,w,h;    while(scanf("%d %d %d",&n,&w,&h)!=EOF)    {        for(int i=1;i<=n;i++)        {            scanf("%d %d",&enves[i].w,&enves[i].h);enves[i].num = i;        }        sort(enves+1,enves+n+1,cmp);        enves[0].w = w;        enves[0].h = h;        int k=0,e,tmp;        dp[0]=0;        for(int i=1;i<=n;i++)        {            dp[i]=1;pre[i]=i;        }        for(int i=0;i<=n;i++)        {            for(int j=0;j<i;j++)            {                if(enves[0].w<enves[j].w&&enves[0].h<enves[j].h&&enves[j].w<enves[i].w&&enves[j].h<enves[i].h&&dp[i]<dp[j]+1)                {                    dp[i] = dp[j]+1;                    pre[i] = j;//记录前驱,即从哪个点过来的                }            }        }        for(int i=1;i<=n;i++)        {            if(dp[i]>k&&enves[0].w<enves[i].w&&enves[0].h<enves[i].h)            {                k = dp[i];                e = i;            }//找到最长子序列并记录它的下标        }        tmp = k;        while(tmp>0)        {            ans[tmp] = enves[e].num;            e = pre[e];            tmp--;            //找到子序列中所有的点        }        if(k==0)        {            printf("0\n");        }        else        {            printf("%d\n",k);            for(int i=1;i<k;i++)            {                printf("%d ",ans[i]);            }printf("%d\n",ans[k]);        }    }    return 0;}

   E - Triangle题意:四条边能否组成三角形、蜕化三角形(两边之和等于第三边)思路:p=(a+b+c)/2; s = sqrt(p*(p-a)*(p-b)*(p-c));p*(p-a)*(p-b)*(p-c)>0则为三角形,=0则为蜕化三角形,<0则无法组成三角形 
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 200+5;const int MAX = 2147483647;int prime [25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};int arr[4];int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);//    srand((unsigned)time(NULL));    while(scanf("%d %d %d %d",&arr[0],&arr[1],&arr[2],&arr[3])!=EOF)    {        int ans=0,flag=0;        double p,tmp;        for(int i=0;i<4;i++)        {            p = 0;            for(int j=0;j<4;j++)            {                if(j==i)continue;                p += arr[j];            }            p/=2.0;            tmp = p;            for(int j=0;j<4;j++)            {                if(i==j)continue;                tmp *= (p-arr[j]);            }//            printf("===%.2lf\n",tmp);            if(tmp>0)            {                printf("TRIANGLE\n");                flag = 1;                break;            }else if(tmp==0)            {                ans += 0;            }else            {                ans += -1;            }        }        if(!flag)        {            if(ans>-4)            {                printf("SEGMENT\n");            }else            {                printf("IMPOSSIBLE\n");            }        }    }}

  President's Office题意:给出一个办公室的分布图,给出经理的位置,求有多少员工跟经理相邻思路:遍历整个图即可    G - Alice, Bob and Chocolate题意:n个糖果,AliceBob一起吃,Alice从左到右吃,Bob从右到左吃,吃每个糖果需要ti的时间,如果两个人同时吃一个时,Bob会让Alice先吃,以体现它的绅士风度。问最后Alice吃了多少个糖果。思路:计算前i个糖果的和sum[i],如果Alice吃到第i个糖果时,sum[i] > sum[n]-sum[i+1]&&sum[i]<sum[n]-sum[i] 时,Alice吃到最多的糖果。 
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <ctime>#include <cstdlib>#include <set>#include <queue>#include <map>using namespace std;typedef long long LL;const double PI = acos(-1);const int N = 100000+5;const int MAX = 2147483647;int prime [25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};int arr[N],sum[N];int main(){//    freopen("in.txt","r",stdin);//    freopen("out.txt","w",stdout);//    srand((unsigned)time(NULL));    int n;    while(scanf("%d",&n)!=EOF)    {        sum[0]=0;        for(int i=1;i<=n;i++)        {            scanf("%d",&arr[i]);            sum[i] = sum[i-1]+arr[i];        }        if(n==1)        {            cout<<"1 0"<<endl;            continue;        }        for(int i=1;i<n;i++)        {            if(sum[i]==(sum[n]-sum[i+1]))            {                cout<<i+1<<" "<<n-(i+1)<<endl;                break;            }else if(sum[i]>(sum[n]-sum[i+1]))            {                cout<<i<<" "<<n-i<<endl;                break;            }        }    }}