Codeforces Beta Round #2 练习
来源:互联网 发布:数据挖掘 数学基础 编辑:程序博客网 时间:2024/06/03 14:11
A题:模拟题,仔细点就好
B题:DP
给你一个数字矩阵,要求从左上角走到右下角的一条路径,这条路径上的数乘起来后末尾的0的个数最少
末尾的0是由2、5产生的,于是联想一下是不是走2最少的一条路或者5最少的一条路就ok了呢?
嗯,就是ok的.*_*
假设从左上角走到右下角走过的数含因子2的最小的个数是x,5的最小的个数是y,则答案是min(x,y),即最优解x、y的个数中有一项是最少的证明:用反证法,假设最优解经过的数含a个2,b个5,a>x,b>y,易得答案肯定大于min(x,y),所以最优解的x、y肯定有一项是最小的
View Code
#include<cstdio>#include<cmath>#include<string>#include<cstdlib>#include<vector>#include<map>#include<set>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int inf = ~0u>>2;const int M = 1010;int dp[M][M][2];int min(int a,int b){ return a<b?a:b;}int main(){ int n,i,j,k,x,y,pos; while(scanf("%d",&n)!=EOF) { pos=-1; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d",&x);y=x; if(x==0) { pos=i; continue; } while(y%2==0){dp[i][j][0]++;y/=2;} while(x%5==0){dp[i][j][1]++,x/=5;} } } for(i=2;i<=n;i++) { dp[i][1][0]+=dp[i-1][1][0]; dp[i][1][1]+=dp[i-1][1][1]; dp[1][i][0]+=dp[1][i-1][0]; dp[1][i][1]+=dp[1][i-1][1]; } for(i=2;i<=n;i++) { for(j=2;j<=n;j++) { dp[i][j][0]+=min(dp[i-1][j][0],dp[i][j-1][0]); dp[i][j][1]+=min(dp[i-1][j][1],dp[i][j-1][1]); } } // printf("%d %d\n",dp[n][n][1],dp[n][n][0]); string ans; k=dp[n][n][0]>dp[n][n][1]; if(pos!=-1&&dp[n][n][k]) { printf("1\n"); for(i=1;i<pos;i++) printf("D"); for(i=1;i<n;i++) printf("R"); for(i=pos;i<n;i++) printf("D"); continue; }i=n;j=n; while(1) { if(dp[i-1][j][k]<dp[i][j-1][k]) { i--; ans+="D"; } else { j--; ans+="R"; } if(i==1) { for(i=1;i<j;i++) ans+="R"; break; } if(j==1) { for(j=1;j<i;j++) ans+="D"; break; } } int len=ans.length(); printf("%d\n",dp[n][n][k]); for(i=len-1;i>=0;i--) { cout<<ans[i]; } cout<<endl; } return 0;}
C题:给你三个圆,求一个点到三个圆的张角相等,如果有多个,选张角最大的那个点
用了爬山算法(模拟退火),不过调了好久的参数才过的
评估函数是当前点到三个圆的张角的方差,每次如果不能获得更优解,就逐渐缩小步长,如果获得了更优解,则始终允许该移动
在走的时候我是往上下左右四个方向走的,可能这也是答案不够准确的原因吧
View Code
#include<cstdio>#include<cmath>const double eps = 1e-6;int dir[4][2]={1,0,0,1,-1,0,0,-1};struct point { double x,y,r;}p[10];int sgn(double x){ return fabs(x)<eps?0:(x>0?1:-1);}double dist(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double judge(point tmp){ int i; double sum=0; double ang[5]; for(i=0;i<3;i++){ ang[i]=dist(p[i],tmp)/p[i].r; sum+=ang[i]; } sum/=3; double vir=0; for(i=0;i<3;i++) vir+=(ang[i]-sum)*(ang[i]-sum); return vir;}int main(){ int i,j,k; double x=0,y=0; for(i=0;i<3;i++){ scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r); x+=p[i].x; y+=p[i].y; } x/=3; y/=3; point s,t; s.x=x;s.y=y; double delta=1,vir1,vir2; while(delta>eps){ vir1=judge(s); for(i=0;i<4;i++){ t.x=s.x+delta*dir[i][0]; t.y=s.y+delta*dir[i][1]; vir2=judge(t); if(vir2<vir1) break; } if(i==4) delta*=0.82;//从0.88一直调到了0.82才摆脱TLE的阴影 else { s.x+=delta*dir[i][0]; s.y+=delta*dir[i][1]; } } if(judge(s)<eps) printf("%.8lf %.8lf\n",s.x,s.y); return 0;}
- Codeforces Beta Round #2 练习
- Codeforces Beta Round #1 练习
- Codeforces Beta Round #3 练习
- Codeforces Beta Round #2
- Codeforces Beta Round #2
- Codeforces Beta Round #2
- Codeforces Beta Round #2
- Codeforces Beta Round #2
- Codeforces Beta Round #2 B
- Codeforces Beta Round #63 (Div. 2)
- Codeforces Beta Round #65 (Div. 2)
- Codeforces Beta Round #67 (Div. 2) ABCD
- Codeforces Beta Round #80 (Div. 2 Only)
- Codeforces Beta Round #83 (Div. 2 Only)
- Codeforces Beta Round #86 (Div. 2 Only)
- Codeforces Beta Round #85 div 2
- Codeforces Beta Round #93 (Div. 2 Only)
- Codeforces Beta Round #95 (Div. 2)
- codeforces 练习 ---- CF 24
- poj 2761 Feed the dogs 求区间第k大的数
- hdu 3333 Turing Tree 成段不重复求和
- Android内存泄露问题(一)之context的引用
- Codeforces Beta Round #1 练习
- Codeforces Beta Round #2 练习
- zoj 3228 Searching the String
- 织梦会员系统bug
- light oj 1427 AC自动机+dfs
- Codeforces Beta Round #3 练习
- CF 4 练习
- 背包输出方案 Pro-Test Voting
- light oj 1135 线段树 有助于加深对懒惰标记的理解
- CF 5 练习