# 2013大连海事大学腾讯编程马拉松div2第二场部分题解

A题：

/****************************************************
* author:crazy_石头
* Pro:
* algorithm:三分
* Time:32ms
* Judge Status:Accepted
*******************************************************/
#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;
}


B题：

HDU1452 好像是。。积性函数。

#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
*******************************************************/
#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;
}


D题

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;
}


G题：

/****************************************************
* author:crazy_石头
* Pro:
* algorithm:
* Time:420ms
* Judge Status:Accepted
*******************************************************/
#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;
}


#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;
}


I题：

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;
}


PS：上面有的代码从网上贴的，未能及时注明出处，请见谅。

• 本文已收录于以下专栏：

举报原因： 您举报文章：2013大连海事大学腾讯编程马拉松div2第二场部分题解 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)