【提高组】神奇的解法
P1007 独木桥
两个人迎面相遇后再调头走,其实等同于两个人穿过对方继续向前走(想象一下在足够高的高空向下看,人是没任何区别的)。
假设人在坐标点p,那么向左走出要走p秒,向右l-p+1秒。那么maxans=max(maxans,max(l-p+1,p)); minans=min(minans,min(l-p+1,p));
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define ri register int #define ll long long #define For(i,l,r) for(ri i=l;i<=r;i++) #define Dfor(i,r,l) for(ri i=r;i>=l;i--) using namespace std; int n,l,p,maxv,minv; inline ll read(){ ll f=1,sum=0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} return f*sum; } int main(){ l=read(),n=read(); For(i,1,n){ p=read(); maxv=max(maxv,max(l-p+1,p)); minv=max(minv,min(l-p+1,p)); } printf("%d %d",minv,maxv); return 0; }
P1984 [SDOI2008]烧水问题
递推+找规律(数学?)。我还被找规律卡了一会儿,数学好差。找规律大法好!
唯一要注意的就是精度在运算和输入输出时的处理,以及运算顺序。像我就是全部硬性转换+疯狂加括号...
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> int n; double res,now; using namespace std; int main(){ cin>>n;now=420000.00/n; for(int i=1;i<=n;i++){ res+=now; now=((double)(2*i-1)/(double)(2*i))*now; } printf("%.2lf\n",res); return 0; }
P2320 [HNOI2006]鬼谷子的钱袋
这道题我说我是用瞪眼法+乱猜法做出来的你信吗...给你一个数n要你输出一堆东西,看着就像递推,然而我想了想简单的递推好像没什么思路,那不会做的数学题就试试看二进制(反正写出来又不亏),发现n元钱要装它的二进制数的位数那么多个袋子;每个袋子要装多少呢,现在共有的钱-现在共有的钱/2,再更新现有的钱,用vector存,倒着输出就行。
但还是要严谨证明下的..用分治,我们拿10举个例子,1是肯定要的;把10分成1~5和6~10,那么6~10可以用1~5加上5即可表示,那么5也要;同理把5也这么分下去。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define ri register int #define ll long long #define For(i,l,r) for(ri i=l;i<=r;i++) #define Dfor(i,r,l) for(ri i=r;i>=l;i--) using namespace std; vector<int>v; ll n; inline ll read(){ ll f=1,sum=0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} return f*sum; } int main(){ n=read(); while(n){ ll tmp=n>>1; v.push_back(n-tmp); n=tmp; } printf("%lld\n",v.size()); Dfor(i,v.size()-1,0) printf("%lld ",v[i]); return 0; }