今天手感还算不错,出了三个题,也有不顺的时候,要不第四题水个小数据或许可以混进前100。总的来说题目很简单,没有什么复杂的东西。
A - Googol String
题意:
目前只考虑包含'0','1'的字符串,有两个操作Switch与Reverse...其中Switch将其中的'0'变成'1','1'变成'0', Reverse将字符串反转
定义:
S0=""
Sn=Sn-1+'0'+Switch(Reverse(Sn-1))
现在已知n=10的100次方,问第k(小于10的18次方)位是0还是1
题解:
其实看到k的范围就知道n这么大的范围只是一个幌子,当n到62的时候,位数已经突破10的18次方位了,所以我觉得两个思路来做,第一个先打表,然后download数据后跑结果,第二个就是我用的在线递归,注意到Sn的长度总是2的n次方-1...就不难写出递归的方法了...
Code:
#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; }
题意:
直接点说就是求D个数之积开D次方的结果。
题解:
很容易想到用log来处理,因为用了log后原本的连乘变成了连加,最后再把结果还原就是。
Code:
#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; }
题意:
给一个图(点的个数小于100,边的个数小于10000),问其中有哪些边是不在任意一个两两间的最短路上的。
题解:
这个之前做过类似的,跑个floyd然后比较下即可..比较坑的是小数据..跑出结果后不敢提交有么有...
Code:
#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; }