A http://acm.hdu.edu.cn/showproblem.php?pid=5112
输入n个时刻和位置,问那两个时刻间速度最快。
解法:按照时间排序,然后依次求相邻两个之间的速度,速度=ds/dt
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int M=1e4+10; 5 struct G{ 6 int t,x; 7 friend bool operator <(const G &a,const G &b){ 8 return a.t<b.t; 9 } 10 }g[M]; 11 int main(){ 12 int t,n; 13 while(~scanf("%d",&t)){ 14 int cas=1; 15 while(t--){ 16 scanf("%d",&n); 17 for(int i=0;i<n;i++){ 18 scanf("%d%d",&g[i].t,&g[i].x); 19 } 20 sort(g,g+n); 21 double ans=0; 22 for(int i=0;i<n-1;i++){ 23 ans=max(ans,abs(g[i].x-g[i+1].x)*1.0/(g[i+1].t-g[i].t)); 24 } 25 printf("Case #%d: %.2f\n",cas++,ans); 26 } 27 } 28 return 0; 29 }
K http://acm.hdu.edu.cn/showproblem.php?pid=5122
输入n的一个排列,问最少多少次操作能将其从小到大排好序, 每次操作可以任意选一个数,不断的往后交换直至后一个大于他停止。
解法:首先选必须要从大往小选,这样最多n次就能排好序,就是逆序的情况。因为如果选个中间的,他往后换的过程可能会遇到一个较大的使得他停下,没达到需要到的位置,从大到小选就避免了这种情况,是最优的方法。问题转化为如何统计步数。我们定义一个需求need,表示当前需要选的数,定义一个指针p,表示当前位置,指针从最后一个位置开始,需求从n开始。每次迭代,若指针的位置的值a【p】恰好等于need,则我们不需要浪费步数,数就在他应该在的位置。若a【p】小于need,说明这个位置应该放的是need,我们需要消耗一步,将前面的need移动至此,但我们不需改动数组的值,因为改动的复杂度是on的。此时我们只需要记录ans++,need--,p不动。若a【p】大于need,说明这个值已经处理过了,p--。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int M=1e6+10; 5 int a[M]; 6 int main(){ 7 int t,n; 8 while(~scanf("%d",&t)){ 9 int cas=1; 10 while(t--){ 11 scanf("%d",&n); 12 for(int i=0;i<n;i++){ 13 scanf("%d",&a[i]); 14 } 15 int ans=0; 16 int p=n-1; 17 for(int i=n;i>=1;i--){ 18 if(a[p]==i){ 19 p--; 20 continue; 21 } 22 if(a[p]>i){ 23 p--; 24 i++; 25 continue; 26 } 27 ans++; 28 } 29 printf("Case #%d: %d\n",cas++,ans); 30 } 31 } 32 return 0; 33 }
end
时间: 2024-10-09 06:20:33