usaco 1.2 Milking Cows(类hash表)

2024-09-09 17:08
文章标签 hash 1.2 usaco cows milking

本文主要是介绍usaco 1.2 Milking Cows(类hash表),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第一种思路被卡了时间 到第二种思路的时候就觉得第一种思路太坑爹了 代码又长又臭还超时!!


第一种思路:我不知道为什么最后一组数据会被卡 超时超了0.2s左右 大概想法是 快排加一个遍历 先将开始时间按升序排好 然后开始遍历比较

1 若 下一个开始beg[i] 小于 tem_end 则说明本组数据与上组数据是在连续的一个区间 取max( ed[i],tem_end )

2 反之 这个区间结束 ans1=max(ans1,tem_end-tem_begin) ,ans2=max(ans2,beg[i]-tem_end)  保存这个区间的答案 并重新给下一个区间戴上开头tem_begin=beg[i],tem_end=ed[i]。直至遍历结束。


目测时间复杂度是快排加遍历就是O(nlogn+n) 不知道为什么会超时 求同学指导。

附上 milk2  TLE  的代码

/*
ID: who jay
LANG: C++
TASK: milk2
*/#include<stdio.h>int max(int a,int b)
{return a>b?a:b;
}void swap(int &a,int &b)
{a=a+b-(b=a);
}void qsort(int A[],int B[],int left,int right)
{int flag=A[left+(right-left)/2];int l=left,r=right;while(A[l]<flag) l++;while(A[r]>flag) r--;if(l<=r){swap(B[l],B[r]);swap(A[l++],A[r--]);}if(l<right) qsort(A,B,l,right);if(left<r) qsort(A,B,left,r);
}int main()
{FILE *fin  = fopen ("milk2.in", "r");FILE *fout = fopen ("milk2.out", "w");int n,i,beg[5000],ed[5000],tem_begin,tem_end;int ans1,ans2;fscanf(fin,"%d",&n);for(i=0; i<n; i++)fscanf(fin,"%d %d",&beg[i],&ed[i]);qsort(beg,ed,0,n-1);tem_begin=beg[0];tem_end=ed[0];ans1=tem_end-tem_begin;ans2=0;for(i=1; i<n; i++){if(beg[i]<=tem_end){tem_end=max(ed[i],tem_end);continue;}else{ans1=max(ans1,tem_end-tem_begin);ans2=max(ans2,beg[i]-tem_end);tem_begin=beg[i];tem_end=ed[i];}}fprintf(fout,"%d %d\n",ans1,ans2);return 0;
}


经过1.3 Mixing milk 的结构体排序的qsort()研究以后 不超时代码:

/*
ID: who jay
LANG: C++
TASK: milk2
*/#include<stdio.h>
#include<algorithm>
using namespace std;struct Milking
{int beg;int ed;
}milk[5000];int milkcmp(const void *va,const void *vb)
{Milking *a,*b;a= (Milking*)va;b= (Milking*)vb;if(a->beg > b->beg)return 1;if(a->beg < b->beg)return -1;return 0;
}int main()
{FILE *fin  = fopen ("milk2.in", "r");FILE *fout = fopen ("milk2.out", "w");int n,i,tem_begin,tem_end;int ans1,ans2;fscanf(fin,"%d",&n);for(i=0; i<n; i++)fscanf(fin,"%d %d",&milk[i].beg,&milk[i].ed);qsort(milk,n,sizeof(Milking),milkcmp);tem_begin=milk[0].beg;tem_end=milk[0].ed;ans1=tem_end-tem_begin;ans2=0;for(i=1; i<n; i++){if(milk[i].beg<=tem_end){tem_end=max(milk[i].ed,tem_end);continue;}else{ans1=max(ans1,tem_end-tem_begin);ans2=max(ans2,milk[i].beg-tem_end);tem_begin=milk[i].beg;tem_end=milk[i].ed;}}fprintf(fout,"%d %d\n",ans1,ans2);return 0;
}




第二种思路 看完第一种思路再看第二种 你会有种被这题深深伤害的赶脚


第二种思路:

1 先将0到1000000时间段赋值为0,表示这段时间没人挤牛奶

2 将输入时间段的点标记为1,表示这段时间有人挤牛奶,并找出有人挤牛奶的最小时间min,最大时间max

3 在最小时间与最大时间之间遍历,

    若 a[i]==1 && a[i+1]==1 表明此刻有人挤牛奶 tempt1++

    若 a[i]==1 && a[i+1]==0 表明下一刻将没有人挤牛奶 temp1++ 并比较temp1与ans1的大小 并令下一段temp1=0

    若 a[i]==0 && a[i+1]==0 表明此刻没有人挤牛奶 temp2++

    若 a[i]==0 && a[i+1]==1 表明下一刻将有人挤牛奶 temp2++ 并比较temp2与ans2的大小 并令下一段temp2=0

4 ko!!!!


这种思路好在 不用排序和区间重合段都被1覆盖 不用再区别

附上代码~

/*
ID: who jay
LANG: C++
TASK: milk2
*/
#include<stdio.h>int main()
{FILE *fin  = fopen ("milk2.in", "r");FILE *fout = fopen ("milk2.out", "w");int i,n,temp1,temp2,start,end,ans1,ans2,min,max;while(fscanf(fin,"%d",&n)!=EOF){temp1=0;temp2=0;ans1=0;ans2=0;min=1000000;max=0;bool a[1000001]={0};while(n--){fscanf(fin,"%d %d",&start,&end);if(min>start)min=start;if(max<end)max=end;for(i=start; i<end; i++)a[i]=1;}for(i=min; i<max; i++){if(a[i]==1 && a[i+1]==1){temp1++;continue;}if(a[i]==1 && a[i+1]==0){temp1++;if(temp1>ans1)ans1=temp1;temp1=0;}if(a[i]==0 && a[i+1]==0){temp2++;continue;}if(a[i]==0 && a[i+1]==1){temp2++;if(temp2>ans2)ans2=temp2;temp2=0;}}fprintf(fout,"%d %d\n",ans1,ans2);}return 0;
}


这篇关于usaco 1.2 Milking Cows(类hash表)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1151763

相关文章

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

hdu1496(用hash思想统计数目)

作为一个刚学hash的孩子,感觉这道题目很不错,灵活的运用的数组的下标。 解题步骤:如果用常规方法解,那么时间复杂度为O(n^4),肯定会超时,然后参考了网上的解题方法,将等式分成两个部分,a*x1^2+b*x2^2和c*x3^2+d*x4^2, 各自作为数组的下标,如果两部分相加为0,则满足等式; 代码如下: #include<iostream>#include<algorithm

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

usaco 1.3 Calf Flac(暴搜)

思路是暴搜。 需要注意的地方是输入的方法,以及输出时的换行。 代码: /*ID: who jayLANG: C++TASK: calfflac*/#include<stdio.h>#include<string.h>#include<math.h>int main(){freopen("calfflac.in","r",stdin);freopen("calfflac.ou

usaco 1.3 Barn Repair(贪心)

思路:用上M块木板时有 M-1 个间隙。目标是让总间隙最大。将相邻两个有牛的牛棚之间间隔的牛棚数排序,选取最大的M-1个作为间隙,其余地方用木板盖住。 做法: 1.若,板(M) 的数目大于或等于 牛棚中有牛的数目(C),则 目测 给每个牛牛发一个板就为最小的需求~ 2.否则,先对 牛牛们的门牌号排序,然后 用一个数组 blank[ ] 记录两门牌号之间的距离,然后 用数组 an

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

usaco 1.2 Palindromic Squares(进制转化)

考察进制转化 注意一些细节就可以了 直接上代码: /*ID: who jayLANG: C++TASK: palsquare*/#include<stdio.h>int x[20],xlen,y[20],ylen,B;void change(int n){int m;m=n;xlen=0;while(m){x[++xlen]=m%B;m/=B;}m=n*n;ylen=0;whi

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (