贪心+数据结构-poj 3110 Jenny's First Exam
来源:互联网 发布:软件动态分析工具 编辑:程序博客网 时间:2024/06/04 19:06
题目链接:
http://poj.org/problem?id=3110
题目意思:
有n科考试,每科考试可以提前di天复习,每科考试只需一天复习,而且要求不能早于考试前di天复习。考试那天不能复习。给n科考试日期,求最晚开始复习的日期。
解题思路:
先把日期全部转化成与0000年00月00日的天数差,然后依据考试时间从晚到早排序,从后往前扫描天数,如果当前天为考试日期,则把该考试的科目加到以按最早复习时间从后往前排序的优先队列,如果当前天没有考试,则从队列中取出队头(表示最晚复习的科目),如果当前时间小于它,则表示不能完成,否则复习该科目。
PS:
1、这种贪心的方式很巧妙,按天数来处理。
2、把天数对应成日期,可以以500年为一个周期,加速处理。
详细解释的代码:
#include<iostream>#include<cmath>#include<cstdio>#include<sstream>#include<cstdlib>#include<string>#include<string.h>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#include<bitset>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define LL long long#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#define M 1000000007#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 55000int n;int yd[2]={365,366};int days[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31};struct DD{ int m,d,y;};struct Sub{ int cur,ea; char save[25]; int dd;}sub[Maxn];bool cmp1(struct Sub a,struct Sub b) //按考试日期从晚到前排序{ return a.cur>b.cur;}int isleap(int y) //是否是润年{ if((y%4==0&&y%100)||(y%400==0)) return 1; return 0;}int dtoi(int y,int m,int d) //将日期转化成距0000年00月00日的天数{ int res=0,yy=isleap(y); res+=y*365+(y-1)/4-(y-1)/100+(y-1)/400; //从第0年开始 for(int i=1;i<m;i++) res+=days[yy][i]; return res+d-1; //注意0表示第一天 1表示第2天}//500年一算 182621DD itod(int cur){ DD res; int i; res.y=cur/182621*500; //也从0开始记 500年为基本单位 for(cur=cur%182621;cur>=yd[isleap(res.y)];res.y++) cur-=yd[isleap(res.y)]; for(i=1;cur>=days[isleap(res.y)][i];i++) cur-=days[isleap(res.y)][i]; res.m=i; res.d=cur+1; //由于有求于 有0所以加1 return res;}struct Inf //优先队列 按最早复习时间 从晚到前 排序{ int d; friend bool operator < (struct Inf a,struct Inf b) { return a.d<b.d; }};int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout);// int sum=0;// for(int i=1;i<=500;i++)// sum+=yd[isleap(i)];// printf("%d\n",sum); //DD dd=itod(0); // printf("%04d.%02d.%02d\n",dd.y,dd.m,dd.d); while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%s",sub[i].save); int y,m,d; scanf("%2d.%2d.%4d",&d,&m,&y); sub[i].cur=dtoi(y,m,d); scanf("%d",&sub[i].dd); sub[i].ea=sub[i].cur-sub[i].dd; } sort(sub+1,sub+1+n,cmp1);// for(int i=1;i<=n;i++)// printf("%d ",sub[i].cur); priority_queue<struct Inf>myq; int la=sub[1].cur,s=1,e=n,le=n; bool ans=false; while(la) //从后往前扫描天数 { bool ha=false; if(sub[s].cur==la) //如果有考试 { struct Inf temp; temp.d=sub[s].ea; myq.push(temp); //把考试加到优先队列里 ha=true; s++; } if(!ha) //如果没有考试 { if(!myq.empty()) //是否有考试没复习 { struct Inf temp=myq.top(); myq.pop(); if(temp.d<=la) //满足复习的条件 le--; else { ans=true; //不行 肯定不能完成 printf("Impossible\n"); break; } } } if(!le) //所有科目都复习完了 { DD tt=itod(la); ans=true; printf("%02d.%02d.%04d\n",tt.d,tt.m,tt.y); break; } la--; } if(!ans) //可能考试重复了 printf("Impossible\n"); } return 0;}/*693963 693961 693960 Impossible*/
0 0
- 贪心+数据结构-poj 3110 Jenny's First Exam
- POJ 3110 Jenny's First Exam (二分 + 树状数组 + 贪心 + 预处理年份)
- jenny
- Saruman's Army 贪心 POJ
- Hdu 5240 Exam【贪心】
- hdoj 5240 Exam【贪心】
- Harry Potter's Exam
- Conclusion of the first exam
- HDOJ 5240 Exam (贪心)
- hdu5240——Exam(贪心)
- poj 3069 Saruman's Army 贪心
- POJ - Saruman's Army(贪心)
- poj 3069Saruman's Army 贪心
- poj 3069 Saruman's Army(贪心)
- poj 2376-Saruman's Army 贪心算法
- POJ 3069 Saruman's Army (贪心)
- POJ 3069 : Saruman\'s Army - 贪心
- POJ 3069 Saruman's Army (贪心)
- oracle中使用cube子句
- iOS---各种控件的创建方法和部分调用方法
- [回溯&&剪枝]Firetruck UVA208
- 【Guava的用法】2. collection
- 仅限于IE的将table中的数据导入导出excel
- 贪心+数据结构-poj 3110 Jenny's First Exam
- Joda--Time简介
- jquery的优缺点
- C++ 双向链表
- 【Guava】Joiner、Splitter源码
- JAVA学习积累
- Eclipse MySQL Hibernate 中文乱码问题 解决方案 心得
- 清空缓冲区
- 如何从Eclipse导入github上的项目源码