HCPC 2011 Spring Online Contest解题报告
来源:互联网 发布:python 基础教程怎么样 编辑:程序博客网 时间:2024/06/07 07:42
A题 RPNF
悲了个催,这种题一直是令我纠结的一种题,表达式求值。。。应该找个时间把这类的正解学下,不能总是现场YY。。。一个堆栈操作的过程,
1.遇到字母直接输出
2.遇到运算符或者左括号op,从栈顶开始,依次与op比较,若优先级大于op,则出栈输出,直到栈为空或者栈顶操作符优先级小于op或者栈顶为'('然后op进栈
3.遇到')',一直出栈,直到栈顶为'('这样就把问题完美解决了代码:
#include <stdio .h>#include <ctype .h>#define N 300char st[N],stack[N];int priority(char op){ switch(op) { case '+':return 0; case '-':return 1; case '*':return 2; case '/':return 3; case '^':return 4; default:return 5; }}bool cmp(char op1,char op2){ return priority(op1)>=priority(op2);}int main(){ int t,i,top; scanf("%d",&t); while(t--) { scanf("%s",st); top=0; for(i=0;st[i];i++) { if(isalpha(st[i]))putchar(st[i]); else { if(st[i]==')') { while(top&&stack[top]!='(')putchar(stack[top--]); top--; } else { while(top&&stack[top]!='('&&cmp(stack[top],st[i]))putchar(stack[top--]); stack[++top]=st[i]; } } } while(top)putchar(stack[top--]); puts(""); } return 0;}
B题 Default Password
o(∩∩)o...哈哈,大水题,让所有人都能happy的过掉,但要比手速。。水题刷刷更健康~~~~
#include <iostream> using namespace std; int main(){ string st; while(cin>>st) { if(st=="wujiawei")cout< <"hit";else cout <<"lose"; cout<<endl; } return 0;}
C题Censorship
额,对题意有些疑问,样例没看懂,感觉第三个样例答案应该是3有空再研究。。。C题The Final Battle of Daydream
题意:给出1..n中的n-2个数,输出少了的两个数
比赛时内存给了1M,但是数据范围是300,000
挂在oj的题上显示给的内存是64M,应该是出问题了吧。。。
起初我就是开了个布尔数组,但是一直超内存,也就超一点点,眼看着别人一个个AC,心里那个滋味啊。。。。
后来看到最下面一行PS. because of the limit memory, iostream is not recommanded.
然后顿悟,去掉了#include<iostream>,然后就AC了
这么做绝对是水过,算一下内存:sizeof(bool)得到1,也就是1个字节,300,000B, 不知道hoj是否算的是字节,问下1+学长
正确的做法是根据给出的数列出两个方程组成方程组,解出答案
a+b=sum(n)-sum(left)
a^2+b^2=sum(n^2)-sum(left^2)
然后解出a和b
正解:
改编自OnePlus学长空间里的解题报告
#include <cstdio>#include <cstring>#include <cmath>#define sqr(x) ((x)*(x))#define PRINT(x) cout < <(#x)<<" "<<x<<endl;using namespace std;int main() { double n; while(scanf("%lf",&n)==1){ double N = 0.0, M = 0.0; for(double i = 1; i <= n; i ++ ) { N = N + i; M = M + sqr(i); } N = ( 1 + n ) * n / 2; M = ( n + 1 ) * ( n*2+1)*n/6; for(int i = 2; i < n; i ++) { double x; scanf( "%lf", &x ); N = N - x; M = M - sqr(x); } double delta = sqrt(2.0 * M - sqr(N)); //printf( "TEST %.10lf %.10lf %.10lf\n", N, M, delta); double x = 0.5 * (N - delta), y = 0.5 * (N + delta); printf( "%.0lf %.0lf\n", x, y ); } return 0;}
水解:
#include <stdio .h>#include <string .h>#define N 300001bool f[N];int main(){ int n,i,a,tot; while(scanf("%d",&n)==1) { memset(f,0,sizeof(f)); tot=0; for(i=0;i<n -2;i++) { scanf("%d",&a); f[a]=1; } for(i=1;i<=n;i++) if(!f[i]) { if(tot)putchar(' '); tot++; printf("%d",i); } puts(""); } return 0;}
E题Costume Party
数学+搜索题
dfs找染色方案,每找出一种染色方案,使用的颜色总数为m1,则ans += A(m,m1)
#include <iostream>#define N 13using namespace std;int tot_edge,n,m,ans;int MOD=9999997;struct data{ int v; data*next;}*adj[N],edge[N*N*2];int visit[N],visitcol[N];void push_edge(int u,int v){ edge[tot_edge].v=v; edge[tot_edge].next=adj[u]; adj[u]=&edge[tot_edge++];}long long a(int n,int m){ long long ans=1; while(m--) { ans=ans*n%MOD; n--; } return ans;}void dfs(int k){ int i; if(k==n) { int totcol=0; for(i=1;i< =n;i++) if(visitcol[i])totcol++; if(totcol<=m)ans=(ans+a(m,totcol))%MOD; return; } data *temp=adj[k]; bool color[N]={false}; while(temp) { if(visit[temp->v]) color[visit[temp->v]]=true; temp=temp->next; } for(i=1;i< =n;i++) if(!color[i]&&visitcol[i]) { visit[k]=i; dfs(k+1); } for(i=1;i<=n;i++) if(!visitcol[i])break; if(i<=n) { visit[k]=i; visitcol[i]=1; dfs(k+1); visitcol[i]=0; } visit[k]=0;}int main(){ int k,a,b,i,cas=1; while(scanf("%d %d %d",&m,&n,&k)==3) { tot_edge=0; memset(adj,0,sizeof(adj)); for(i=0;i<k;i++) { scanf("%d %d",&a,&b); a--; b--; push_edge(a,b); push_edge(b,a); } memset(visit,0,sizeof(visit)); memset(visitcol,0,sizeof(visitcol)); ans=0; dfs(0); printf("Case #%d\n%d\n",cas++,ans); } return 0;}
F题Go Home
我用spfa做的,保留了个二维的读列,但是比较慢,0.22s
看了OnePlus学长博客的<a href="http://www.oneplus.info/archives/230">解题报告</a>,给的做法是堆优化的dijkstra,我用xiaohao2跑了下,0.04s,挺快,直接用的algorithm里的堆(学习下)
OnePlus学长还给了个搜索做的,写的是宽搜,我提交后,时间好慢,0.28s,也许是因为用模板了。。。
看到wdk的只用了0.02s,orz。。。然后问他怎么做到的,他说直接搜索(深搜),看来我水了。。这道题水了。。。搜索竟然比正解快,搜索才是正解。。。。
然后我也写了个深搜,0.01s过掉,回头想了下先前写的spfa,也不过就是宽搜,但是宽搜怎么会比深搜慢那么多倍(都木有用到模板),改了很多次,bfs还是那么慢,纠结。。。。
有谁知道是怎么回事呀。。。
spfa(bfs)写法(变量名有点乱,囧。。。)
#include<stdio .h>#include<string .h>#define M 2010#define N 510#define NN 250010struct data{ int v,co,tm; data*next;}*adj[N],edge[M];int q[NN],f[N][N],cost[NN],visit[N][N];int C,tot_edge,n;void push_edge(int u,int v,int c,int t){ edge[tot_edge].v=v; edge[tot_edge].co=c; edge[tot_edge].tm=t; edge[tot_edge].next=adj[u]; adj[u]=&edge[tot_edge++];}void spfa(){ q[0]=1; cost[0]=C; f[1][C]=0; int head=-1,tail=1,u,t,c; data*tmp; while((head+1)%NN!=tail) { head++; head%=NN; u=q[head]; c=cost[head]; t=f[u][c][/c]; tmp=adj[u]; visit[u][c][/c]=0; while(tmp) { if(c>=tmp->co&&f[tmp->v][c language="-tmp->co"][/c]>t+tmp->tm) { f[tmp->v][c language="-tmp->co"][/c]=t+tmp->tm; if(tmp->v!=n&&tmp->v!=1&&!visit[tmp->v][c language="-tmp->co"][/c]) { q[tail]=tmp->v; cost[tail]=c-tmp->co; visit[tmp->v][c language="-tmp->co"][/c]=1; tail++; tail%=NN; } } tmp=tmp->next; } }}int main(){ int T,t,m,i,u,v,c,INF,ans; scanf("%d",&T); while(T--) { scanf("%d %d %d",&n,&m,&C); tot_edge=0; memset(adj,0,sizeof(adj)); for(i=0;i<m ;i++) { scanf("%d %d %d %d",&u,&v,&c,&t); push_edge(u,v,c,t); push_edge(v,u,c,t); } memset(visit,0,sizeof(visit)); memset(f,127,sizeof(f)); ans=INF=f[0][0]; spfa(); for(i=0;i<=C;i++) if(f[n][i]<ans)ans=f[n][i]; if(ans==INF)puts("-1"); else printf("%d\n",ans); } return 0;}
dfs 写法:
#include<stdio .h>#include<string .h>#define N 510#define M 2010#define INF 1000000000int n,tot_edge,ans;bool visit[N];struct data{ int v,c,t; data * next; void update(int v,int c,int t,data *k) { this->v=v; this->c=c; this->t=t; this->next=k; }}edge[M],*adj[N];void push_edge(int u,int v,int c,int t){ edge[tot_edge].update(v,c,t,adj[u]); adj[u]=&edge[tot_edge++];}void dfs(int k,int left,int tim){ if(tim>=ans)return; if(k==n)ans=tim; else { visit[k]=true; data*temp=adj[k]; while(temp) { if(!visit[temp->v]&&left>=temp->c) dfs(temp->v,left-temp->c,tim+temp->t); temp=temp->next; } visit[k]=false; }}int main(){ int t,i,a,b,c,m,C,T; scanf("%d",&T); while(T--) { scanf("%d %d %d",&n,&m,&C); tot_edge=0; memset(adj,0,sizeof(adj)); for(i=0;i<m ;i++) { scanf("%d %d %d %d",&a,&b,&c,&t); push_edge(a,b,c,t); push_edge(b,a,c,t); } ans=INF; memset(visit,false,sizeof(visit)); dfs(1,C,0); if(ans==INF)puts("-1"); else printf("%d\n",ans); }}
dijkstra+堆优化:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int N = 505;const int INF = 0x3fffffff;int first[N];int cnt = 1;struct edge{ int u, v, c, t, next;} g[N * 4];void add(int u, int v, int c, int t){ g[cnt].u = u; g[cnt].v = v; g[cnt].c = c; g[cnt].t = t; g[cnt].next = first[u]; first[u] = cnt++;}struct node{ int w, u, t; bool operator < ( const node &a ) const { return t > a.t; }};int n, m, C;int dis[N][N];bool used[N][N];node queue[N * N];bool relax(int u, int w, int v, int c, int t){ if (dis[u][w] + t < dis[v][w + c]) { dis[v][w + c] = dis[u][w] + t; return true; } return false;}void dij(int u){ for (int i = 0; i <= n; ++i) for (int j = 0; j <= C; ++j) dis[i][j] = INF; memset(used, false, sizeof(used)); int tail = 0; int v, w, c, t; dis[u][0] = 0; queue[tail].u = u; queue[tail].w = 0; queue[tail].t = 0; tail++; make_heap(queue, queue + tail); while (tail > 0) { pop_heap(queue, queue + tail); tail--; u = queue[tail].u; if ( u == n ) break; w = queue[tail].w; if ( !used[u][w] ) { used[u][w] = true; for (int tmp = first[u]; tmp ; tmp = g[tmp].next) { v = g[tmp].v; c = g[tmp].c; t = g[tmp].t; if ( w + c < = C && !used[v][w + c] && relax(u, w, v, c, t) ) { queue[tail].u = v; queue[tail].w = w + c; queue[tail].t = dis[v][w + c]; tail++; push_heap(queue, queue + tail); } } } } return;}int main(){ int cases, u, v, c, t; scanf("%d", &cases); while (cases--) { memset(first, 0, sizeof(first)); cnt = 1; scanf("%d %d %d", &n, &m, &C); // n:1~n for (int i = 0; i < m; ++i) { scanf("%d %d %d %d", &u, &v, &c, &t); add(u, v, c, t); add(v, u, c, t); } dij(1); int ans = INF; for (int i = C; i >= 0; --i) { if (dis[n][i] != INF) { ans = min(ans, dis[n][i]); } } printf("%d\n", ans == INF ? -1 : ans); } return 0;}
G题Alex's Problem
求截面面积。。。。坑爹啊。。。。更坑爹的是学长竟然做下来啦。。。
Alex 的problem很严重啊
没那份耐心去想,此题报告待写。。。
H题Zhou Yi II
二进制转十进制。。。。
#include <iostream> using namespace std; int main(){ char st[100]; int n,i,ans; while(scanf("%d",&n)==1) { getchar(); ans=0; for(i=0;i<n ;i++) { gets(st); ans<<=1; if(strcmp(st,"---")) ans++; } printf("%d\n",ans); } return 0;}
Okay,网络赛的报告就写到这,其中两道题待做,会尽快做掉。。。。
就这报告还写了这么长时间。。。。咳咳。。。不过很爽,很久都没安静做题了,这回泡在图书馆一下午+晚上,安安静静的做完这些事,挺好。。。。
- HCPC 2011 Spring Online Contest解题报告
- 2011 大连网络赛 The 36th ACM/ICPC Asia Regional Dalian Site —— Online Contest 解题报告
- [Contest] THUSC 2016 解题报告
- USTC Monthly Contest 2011-04-10 / 解题报告
- 九度Online Judge解题报告
- 1111. Online Map (30)解题报告
- Spring Outing 解题报告
- School Team Contest #2 ABCEH 解题报告
- HIT summer training Contest 11 / 解题报告
- 某个contest几道解题报告
- 2012 East Central Regional Contest 解题报告
- 2014 Multi-University Training Contest 解题报告
- 【WHUST 2016 Individual Contest #1】解题报告
- 【WHUST 2016 Individual Contest #2】解题报告
- 【WHUST 2016 Individual Contest #3 】解题报告
- LeetCode Weekly Contest 56 解题报告
- [Leetcode] 544. Output Contest Matches 解题报告
- Sichuan University Programming Contest 2011 Preliminary(for Non-SCUers) / 解题报告 4.4
- php编程,打印url传过来的中文是乱码
- apache(单机)负载均衡配置(四)
- jdk1.4 jdk1.5 jdk1.6 jdk1.7
- c#,gdi+,画函数图形,坐标系,如f(x)=sin(x)
- xcode3.2 svn配置和使用
- HCPC 2011 Spring Online Contest解题报告
- apache(单机)负载均衡配置(五)
- MIME Type?
- php常用函数
- C#_WinForm窗体传值
- Spring2 JDBC 连接池
- 目录下有个.h.gch文件,是什么?
- 文本框中输入Enter键 激发某个按钮的Click事件
- 在hibernate中对象的几种状态