A题:
条件反射,看到函数求极值果断先往三分上想,没错,这题就是个三分。
/**************************************************** * author:crazy_石头 * Pro: * algorithm:三分 * Time:32ms * Judge Status:Accepted *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> using namespace std; #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) #define eps 1e-8 #define INF 1<<29 #define LL __int64 const int maxn=200000+5; double A,B; inline double solve(double l,double r) { double mid; while(r - l >= eps) { mid = (l+r)/2; double midmid = (mid+r)/2; double tmp1 = mid * (A - B*mid)*pow(B,mid); double tmp2 = midmid * (A - B * midmid)*pow(B ,midmid); if(tmp1 > tmp2) r = midmid; else l = mid; } return mid * (A - mid*B)*pow(B,mid); } int main() { while(cin>>A>>B) { printf("%.3lf\n",solve(0,A/B)); } return 0; }
HDU1452 好像是。。积性函数。
贴一下别人的精简代码。。http://www.cnblogs.com/dyllove98/p/3192154.html
#include<cstdio> #include<cstdlib> using namespace std; typedef __int64 ll; ll powmol(ll x,ll y)//高次幂取模的求x^ymod29 { ll ans=1; x=x%29; while(y) { if(y&1)ans*=x%29;//y是奇数情况的处理; x=x*x%29; y>>=1;// } return ans; } int main() { ll x,a,b,c; while(scanf("%I64d",&x),x) { a=(powmol(2,2*x+1)-1)%29; b=(powmol(3,x+1)-1)*15%29; c=(powmol(22,x+1)-1)*18%29; printf("%I64d\n",(a*b)%29*c%29); } return 0; }
C题:
好像也是原题,好无聊。。。
/**************************************************** * author:crazy_石头 * Pro: * algorithm: * Time:32ms * Judge Status:Accepted *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> using namespace std; #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) #define eps 1e-6 #define INF 1<<29 #define LL __int64 const int maxn=200+5; const int maxm=1000000+10; int main() { int a,b; int res[maxn] bool ok=0; int len=0; int i=0,j=0; char wall[maxn][maxn]; ms(res,0); cin>>a>>b; rep(i,1,a) rep(j,1,b) cin >> wall[i][j]; rep(j,1,b) { rep(i,1,a) { if(wall[i][j]=='0') { if(!ok) { len = 1; ok=1; } else len++; } else { if (len!=0) { res[len]++; ok=0; len=0; } } } if (len!=0) { res[len]++; ok=0; len= 0; } } rep(i,1,200) if (res[i]!=0) cout<<i<<" "<<res[i]<<endl; return 0; }
BFS搞定。。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=250; const int INF=0x3f3f3f3f; struct node{ int x,y; int door; bool operator < (const node &a) const{ return a.door<door; } }; int n,m,sx,sy,maxx,maxy; int dis[N][N],h[N][N],l[N][N]; void BFS(){ priority_queue<node> q; while(!q.empty()) q.pop(); for(int i=0;i<=maxx;i++) for(int j=0;j<=maxy;j++) dis[i][j]=INF; node cur; cur.x=0, cur.y=0, cur.door=0; dis[0][0]=0; q.push(cur); while(!q.empty()){ cur=q.top(); q.pop(); int x=cur.x, y=cur.y; if(x==sx && y==sy) return ; if(y+1<=maxy && dis[x][y+1]>dis[x][y]+h[x][y+1]){ //向上走 dis[x][y+1]=dis[x][y]+h[x][y+1]; cur.x=x; cur.y=y+1; cur.door=dis[x][y+1]; q.push(cur); } if(y-1>=0 && dis[x][y-1]>dis[x][y]+h[x][y]){ //向下走 dis[x][y-1]=dis[x][y]+h[x][y]; cur.x=x; cur.y=y-1; cur.door=dis[x][y-1]; q.push(cur); } if(x-1>=0 && dis[x-1][y]>dis[x][y]+l[x][y]){ //向左走 dis[x-1][y]=dis[x][y]+l[x][y]; cur.x=x-1; cur.y=y; cur.door=dis[x-1][y]; q.push(cur); } if(x+1<=maxx && dis[x+1][y]>dis[x][y]+l[x+1][y]){ //向右走 dis[x+1][y]=dis[x][y]+l[x+1][y]; cur.x=x+1; cur.y=y; cur.door=dis[x+1][y]; q.push(cur); } } dis[sx][sy]=-1; } int main(){ //freopen("input.txt","r",stdin); int x,y,d,t; double f1,f2; while(~scanf("%d%d",&n,&m)){ if(n==-1 && m==-1) break; maxx=-1, maxy=-1; memset(h,0,sizeof(h)); memset(l,0,sizeof(l)); while(n--){ scanf("%d%d%d%d",&x,&y,&d,&t); if(d==0){ for(int i=0;i<t;i++) h[x+i][y]=INF; maxx=max(maxx,x+t); maxy=max(maxy,y); }else{ for(int i=0;i<t;i++) l[x][y+i]=INF; maxx=max(maxx,x); maxy=max(maxy,y+t); } } while(m--){ scanf("%d%d%d",&x,&y,&d); if(d==0) h[x][y]=1; else l[x][y]=1; } scanf("%lf%lf",&f1,&f2); if(f1>maxx || f2>maxy){ puts("0"); continue; } sx=(int)f1, sy=(int)f2; BFS(); printf("%d\n",dis[sx][sy]); } return 0; }
可以看做最小生成树吧
/**************************************************** * author:crazy_石头 * Pro: * algorithm: * Time:420ms * Judge Status:Accepted *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> using namespace std; #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) #define eps 1e-6 #define INF 1<<29 #define LL long long const int MAXN=10000000; int n,r; int c[MAXN]; int parent[MAXN]; bool visited[MAXN]; int next[MAXN]; int prev[MAXN]; int rank[MAXN]; int sum[MAXN]; inline int find() { double max=0; int i,flg=-1; for(i=1;i<=n;i++) if(max<sum[i]*1.0/rank[i] && !visited[i]) { max=sum[i]*1.0/rank[i]; flg=i; } return flg; } inline void uni(int x) {//合并节点,并把他们按顺序排好 int i; for(i=parent[x];prev[i]!=-1;i=prev[i]); //合并节点 rank[i]+=rank[x]; sum[i]+=sum[x]; for(i=parent[x];next[i]!=-1;i=next[i]); //排序,接到最后一个节点上 next[i]=x; prev[x]=i; visited[x]=true; } int main() { while(scanf("%d %d",&n,&r),n && r) { int i; for(i=1;i<=n;i++) { scanf("%d",&c[i]); visited[i]=false; prev[i]=next[i]=-1; rank[i]=1; //合并后,集合中的规模 sum[i]=c[i]; //集合的和 } for(i=1;i<n;i++) { //输入n-1个节点的父子关系 int a,b; scanf("%d %d",&a,&b); parent[b]=a; } visited[r]=true; while(true) { int u=find(); if(u==-1) break; uni(u); } int cnt=0,ans=0; //cnt用于记录时间 for(i=r;i!=-1;i=next[i]) ans+=(++cnt)*c[i]; printf("%d\n",ans); } return 0; }
H题:
数论,现在还不太会推。从OEIS上面搜的公式。给n个结点,问能形成多少个不同的对。好像。
#include <stdio.h> #include <math.h> #include <string.h> #include <iostream> #include <algorithm> #define MOD 20000003 #define LL long long using namespace std; LL ex[40]; LL dp[1100000]; LL jc[1100000]; LL pown(LL a,LL b,LL c) { LL scc,ret; if (b==0) return 1; else if (b==1) return a%c; if (b&1) ret=a;else ret=1; scc=pown(a,b/2,c); return ret*scc%c*scc%c; } LL cc(LL n,LL m) { LL x,y,z; x=jc[n]; y=jc[m]*jc[n-m]%MOD; z=pown(y,MOD-2,MOD); x=(1LL)*x*z%MOD; return x; } LL getnumber(LL x) { if (dp[x]!=-1) return dp[x]; LL num=(log(x)/log(2)); LL i=1; LL s1=ex[num-1]-1,s2=s1; LL t=x-ex[num]+1; LL xx=ex[num-1]; s1=s1+min(t,xx); if (t>xx) s2=s2+t-xx; dp[x]=((1LL)*cc(x-1,s1)*getnumber(s1)%MOD*getnumber(s2)%MOD); return (dp[x]); } int main() { LL i,j,k,l,n,m; memset(dp,-1,sizeof(dp)); dp[0]=1; dp[1]=1; dp[2]=1; dp[3]=2; ex[0]=1; for (i=1;i<=29;i++) ex[i]=ex[i-1]*2; jc[0]=1; jc[1]=1; for (i=2;i<=1000000;i++) jc[i]=(1LL)*jc[i-1]*i%MOD; while (scanf("%lld",&n)!=EOF) { printf("%lld\n",getnumber(n)); } return 0; }
模拟。。
N题:
模拟剪刀石头布,很水的模拟题,直叙式模拟。。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int win[105],lose[105]; inline int comp(char s1[],char s2[]) { switch(s1[0]) { case 'r': switch(s2[0]) { case 'r': return 0; case 'p': return -1; case 's': return 1; } break; case 'p': switch(s2[0]) { case 'r': return 1; case 'p': return 0; case 's': return -1; } break; case 's': switch(s2[0]) { case 'r': return -1; case 'p': return 1; case 's': return 0; } } } int main() { int n,k; bool first=true; while(scanf("%d%d",&n,&k)!=EOF&&n) { memset(win,0,sizeof(win)); memset(lose,0,sizeof(lose)); if(first) first=false; else printf("\n"); int all=k*n*(n-1)/2; for(int i=0; i<all; i++) { int a,b,c; char s1[10],s2[10]; scanf("%d%s%d%s",&a,s1,&b,s2); c=comp(s1,s2); if(c==1) win[a]++,lose[b]++; else if(c==-1) win[b]++,lose[a]++; } for(int i=1;i<=n;i++) { if(win[i]+lose[i]==0) printf("-\n"); else printf("%.3lf\n",(double)(win[i])/(double)(win[i]+lose[i])); } } return 0; }