今天手感还算不错,出了三个题,也有不顺的时候,要不第四题水个小数据或许可以混进前100。总的来说题目很简单,没有什么复杂的东西。
A - Googol String
其实看到k的范围就知道n这么大的范围只是一个幌子,当n到62的时候,位数已经突破10的18次方位了,所以我觉得两个思路来做,第一个先打表,然后download数据后跑结果,第二个就是我用的在线递归,注意到Sn的长度总是2的n次方-1...就不难写出递归的方法了...
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
using namespace std;
int dfs(long long k,long long h){
if (k==((h-1)/2))
return 0;
if (k<(h/2-1))
return dfs(k,h/2);
else{
k=h-2-k;
return 1-dfs(k,h/2);
}
}
int main(){
freopen("A-small-attempt0.in.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
cin>>T;
long long c=1;
for (int i=1;i<=62;i++) c=c*2;
for (int cases=1;cases<=T;cases++){
long long k;
cin>>k;
k--;
cout<<"Case #"<<cases<<": "<<dfs(k,c)<<endl;
}
return 0;
}
B - gCube
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
using namespace std;
const int MAXN=100005;
int a[MAXN];
int main(){
freopen("B-large.in.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
scanf("%d",&T);
for (int cases=1;cases<=T;cases++){
int n,m;
scanf("%d%d",&n,&m);
for (int i=0;i<n;i++) scanf("%d",&a[i]);
printf("Case #%d:\n",cases);
while (m--){
int L,R,D;
scanf("%d%d",&L,&R);
D=(R-L+1);
double ans=0;
for (int i=L;i<=R;i++) ans+=log2(a[i]);
ans/=D;
printf("%.10lf\n",pow(2,ans));
}
}
return 0;
}
C - gCampus
这个之前做过类似的,跑个floyd然后比较下即可..比较坑的是小数据..跑出结果后不敢提交有么有...
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map>
using namespace std;
const int MAXN=20005;
struct Edge{
int u,v,c;
}edge[MAXN];
int dis[105][105];
int ABS(int x){
if (x<0) return -x;
return x;
}
void Floyd(int n){
for (int k=0;k<n;k++)
for (int u=0;u<n;u++)
for (int v=0;v<n;v++)
if (dis[u][v]-dis[u][k]>dis[k][v])
dis[u][v]=dis[u][k]+dis[k][v];
}
bool f[MAXN];
int main(){
freopen("C-small-attempt0.in.txt","r",stdin);
freopen("output.txt","w",stdout);
int T;
scanf("%d",&T);
for (int cases=1;cases<=T;cases++){
int n,m;
scanf("%d%d",&n,&m);
memset(dis,0x7f,sizeof(dis));
for (int i=0;i<n;i++) dis[i][i]=0;
for (int i=0;i<m;i++){
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
edge[i].u=u,edge[i].v=v,edge[i].c=c;
dis[u][v]=min(dis[u][v],c);
dis[v][u]=min(dis[v][u],c);
}
printf("Case #%d:\n",cases);
Floyd(n);
memset(f,false,sizeof(f));
for (int s=0;s<n;s++)
for (int t=0;t<n;t++)
for (int k=0;k<m;k++)
if (dis[s][edge[k].u]+edge[k].c+dis[edge[k].v][t]==dis[s][t])
f[k]=true;
for (int i=0;i<m;i++)
if (!f[i]) printf("%d\n",i); //
}
return 0;
}