hdu刷題
阿新 • • 發佈:2018-07-22
mat 關系 mod hdu sin mmm void truct 查找
1002 大數加法
#include<iostream> #include<cstring> using namespace std; int main() { char a[1002],b[1002]; int c[1002]; int n; cin>>n; for(int w=1;w<=n;w++) { int i=0,k=0,j=0; memset(c,0,sizeof(c)); cin>>a>>b; int l1=strlen(a);View Codeint l2=strlen(b); l1--,l2--; while(1) { c[k]=c[k]+(a[l1]+b[l2]-‘0‘-‘0‘); l1--; l2--; k++; if(l1==-1||l2==-1) break; } if(l1==-1&&l2!=-1) { while(l2!=-1){ c[k]=c[k]+(b[l2]-‘0‘); k++; l2--; } } else if(l1!=-1&&l2==-1) { while(l1!=-1){ c[k]=c[k]+(a[l1]-‘0‘); k++; l1--; } } for(i=0;i<k;i++) { if(c[i]>=10&&i!=k-1) { c[i+1]+=c[i]/10; c[i]%=10; } else if(c[i]>=10&&i==k-1) { c[i+1]+=c[i]/10; c[i]%=10; k++; } } cout<<"Case "<<w<<":"<<endl; cout<<a<<" + "<<b<<" = "; if(w!=n) { for(i=k-1;i>=0;i--) { cout<<c[i]; } cout<<endl; cout<<endl; } else{ for(i=k-1;i>=0;i--) { cout<<c[i]; } cout<<endl; } } }
1003 簡單采用了dp的思想吧,這一個與上一個有關系,關鍵是找到這個關系
#include<iostream> #include<string.h> using namespace std; int a[100002]; int dp[100002]; int main() { int t; cin>>t; for(int i=1;i<=t;i++) { int n; cin>>n; for(int j=1;j<=n;j++) cin>>a[j]; memset(dp,0,sizeof(dp)); int s=1,l=1,r=1; int maxsum=a[1]; dp[1]=a[1]; for(int k=2;k<=n;k++) { if(dp[k-1]>=0) dp[k]=dp[k-1]+a[k]; else { dp[k]=a[k]; s=k; } if(dp[k]>maxsum) { maxsum=dp[k]; l=s; r=k; } } printf("Case %d:\n",i); printf("%d %d %d\n", maxsum, l, r); if(i!=t) printf("\n"); } }View Code
1005 定義 f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
給出A B 和N 求f(n) 思路就是找規律 如果循環中出現了兩個連續的1 則說明循環出現
#include<bits/stdc++.h> using namespace std; int x[10000]; int main() { int a,b,c; while(cin>>a>>b>>c) { if(a==0&&b==0&&c==0) break; memset(x,0,sizeof(x)); x[1]=1,x[2]=1; int i; for(i=3;i<=1000;i++) { x[i]=(x[i-1]*a+x[i-2]*b)%7; if(x[i]==1&&x[i-1]==1) break; } c=c%(i-2); x[0] = x[i-2]; cout<<x[c]<<endl; } }View Code
1007
給n個點的坐標,求距離最近的一對點之間距離的一半。
第一行是一個數n表示有n個點,接下來n行是n個點的x坐標和y坐標。實數。
emmmm 這個分治思想比較好吧
#include<iostream> #include<cmath> #include<algorithm> using namespace std; int n; struct node { double x; double y; }p[100005]; int a[100005]; double cmpx(node a,node b) { return a.x<b.x; } double cmpy(int a,int b) { return p[a].y<p[b].y; } double dis(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double find(int l,int r){ if(r==l+1) //如果只有一個或者兩個點直接求最短長度 return dis(p[l],p[r]); if(l+2==r) return min(dis(p[l],p[r]),min(dis(p[l],p[l+1]),dis(p[l+1],p[r]))); //遞歸求解 int mid=(l+r)>>1; //從中間分開,進行分治 double ans=min(find(l,mid),find(mid+1,r)); //尋找左右兩邊最小值 int i,j,cnt=0; for(i=l;i<=r;i++){ //統計距離中點距離小於ans的點 if(p[i].x>=p[mid].x-ans&&p[i].x<=p[mid].x+ans) a[cnt++]=i; } sort(a,a+cnt,cmpy); //對y軸進行排序 for(i=0;i<cnt;i++){ //查找是否存在最小的點 for(j=i+1;j<cnt;j++){ if(p[a[j]].y-p[a[i]].y>=ans) break; ans=min(ans,dis(p[a[i]],p[a[j]])); } } return ans; } int main(){ int i; while(scanf("%d",&n)!=EOF){ if(!n) break; for(i=0;i<n;i++) scanf("%lf %lf",&p[i].x,&p[i].y); sort(p,p+n,cmpx); printf("%.2lf%\n",find(0,n-1)/2); } return 0; }View Code
1010
深搜再加上奇偶剪枝
#include<iostream> #include<string.h> using namespace std; char a[10][10]; int n,m,t; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int sx,sy,ex,ey; int f=0; int abs(int x) { return x<0?-a:x; } void dfs(int x,int y,int tt) { if(x==ex&&y==ey&&tt==t) { f=1; return ; } int temp=(t-tt)-(abs(x-ex)+abs(y-ey));//在這一點(我能走的步數)減去(這一點我到終點的最小步數)如果不是偶數或者小於零,則不能走到 if(temp<0||temp&1) return ; for(int i=0;i<4;i++) { int xx=x+dx[i]; int yy=y+dy[i]; if(a[xx][yy]!=‘X‘&&xx>=0&&xx<n&&yy>=0&&yy<m) { a[xx][yy]=‘X‘; DFS(xx,yy,tt+1); a[xx][yy]=‘.‘; if(flag)return ; } } } int main() { while(cin>>n>>m>>t) { if(n==0&&m==0) break; int wall=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>a[i][j]; if(a[i][j]==‘S‘) sx=i,sy=j; else if(a[i][j]==‘D‘) ex=i,ey=j; else if(a[i][j]==‘X‘) wall++; } } if(n*m-wall<=t) { cout<<"NO"<endl; continue; } f=0; a[sx][sy]=‘X‘; dfs(sx,sy,0); if(f==1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }View Code
1011
樹形dp
#include<iostream> #include<string.h> using namespace std; int dp[105][105]; int a[105][105]; int value[105]; int p[105]; int v,n,vis[105]; int max(int a1,int a2) { return a1>a2?a1:a2; } int dfs(int now,int pre)//now 是當前節點 pre是上一個節點 { int tem=(value[now]+19)/20; //tem是這個節點需要的士兵 for(int k=tem;k<=v;k++) { dp[now][k]=p[now]; //dp[now][tem++]=p[now] 意思是不管這個節點派多少大於tem士兵 得到的p都是一樣 } for(int i=1;i<=n;i++) //遍歷每個節點 { if(a[now][i]==1&&i!=pre) //如果是now連著的下一個地點 並且下一個地點不是自己 { dfs(i,now); //再次搜索。。。搜到底了時 for(int j=v;j>=tem;j--)//j是排出的士兵數 { for(int k=1;k<=j-tem;k++)//j-tem是 { dp[now][j]=max(dp[now][j],dp[now][j-k]+dp[i][k]);//k的範圍為1-(j-tem),因為你至少要留下tem個士兵來攻打當前節點,i為該節點的子節點 } } } } return 0; } int main() { while(cin>>n>>v) { if(n==-1&&v==-1) break; for(int i=1;i<=n;i++) cin>>value[i]>>p[i]; memset(a,0,sizeof(a)); for(int j=0;j<n-1;j++) { int t1,t2; cin>>t1>>t2; a[t1][t2]=1; a[t2][t1]=1; } if(v==0) { cout<<"0"<<endl; continue; } memset(dp,0,sizeof(dp)); dfs(1,-1); cout<<dp[1][v]<<endl; } return 0; }View Code
1016
輸入n 輸出一個素數環,就是相鄰數為素數的一個環
#include<iostream> #include<bits/stdc++.h> using namespace std; int p[1000]; int a[100],vis[100]; int ans[100]; int cnt; int n; void dfs(int s,int step) { if(step==n) { if(p[1+ans[n-1]]==0) { for(int i=0;i<n;i++) { if(i==0) cout<<ans[i]; else cout<<" "<<ans[i]; } cout<<endl; return; } else return ; } for(int i=1;i<=n;i++) { if(!vis[i]&&p[i+s]==0) { vis[i]=1; ans[step]=i; dfs(i,step+1); vis[i]=0; } } } int main() { memset(p,0,sizeof(p)); p[1]=1; for(int i=2;i<=800;i++) { if(p[i]==0) { for(int j=i*2;j<800;j+=i) p[j]=1; } } // for(int i=1;i<=20;i++) cout<<p[i]<<endl; int ii=1; while(cin>>n){ for(int i=1;i<=n;i++) a[i]=i; printf("Case %d:\n",ii); ans[0]=1; vis[1]=1; dfs(1,1); ii++; cout<<endl; } }View Code
1018
輸入一個數,然後輸出這個數階乘有多少位
竟然還有log10(x)....123456=1.23456×10^5 兩邊同時求對數log10(123456)=5+0.x.....
#include<iostream> #include<math.h> using namespace std; int main() { int n,test,ans=0; double t; cin>>test; while(test--) { cin>>n; t=0; for(int i=2;i<=n;i++) { t+=log10(i*1.0); } ans+=(int)t+1; cout<<ans<<endl; ans=0; } return 0; }View Code
hdu刷題