2015.3.22 湖南多校对抗赛(第二场)
比赛还是有差距,还是很多题目没有A出来
A:
给定两个01串,每次进行的操作就是交换相邻的两位,问到达目标串的最小变换次数是多少
当时是模拟做出来的,后来用状压+BFS再写了一遍
http://www.cnblogs.com/clliff/p/4363100.html
B:
B题就是给定一个算式,问是按照乘法优先顺序得到答案还是从左至右算得到答案,模拟一遍就好
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<ctype.h> #include<queue> #include<stack> #include<stdlib.h> #include<algorithm> using namespace std; const int MAXN=20+5; char str[MAXN]; int ans,b[MAXN]; stack<int> S; int main() { scanf("%s",str); scanf("%d",&ans); int len=strlen(str); for(int i=0;i<len;i++) { if(i%2==0) S.push(str[i]-'0'); if(str[i]=='*') { i++; int temp=S.top(); S.pop(); S.push(temp*(str[i]-'0')); } } int ans1=0; while(!S.empty()) { int temp=S.top(); S.pop(); ans1+=temp; } int ans2=str[0]-'0'; for(int i=1;i<len;i++) { if(str[i]=='+') { i++; ans2+=str[i]-'0'; } if(str[i]=='*') { i++; ans2*=str[i]-'0'; } } if(ans1==ans && ans2!=ans) printf("M\n"); if(ans1!=ans && ans2==ans) printf("L\n"); if(ans1==ans && ans2==ans) printf("U\n"); if(ans1!=ans && ans2!=ans) printf("I\n"); return 0; }
C:
一个人要买东西,只能买完后面的物品之后才能买前面的物品,问最少走的路程是多少
那么每次就只用判断给出的区间是否有交集,如果有交集就把两个区间合并起来,最后每个区间宽度*3(去回去)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<stdlib.h> #include<queue> #include<algorithm> #include<vector> #include<ctype.h> #define LL __int64 using namespace std; const double EPS=1e-9; const int MAXN=1000+10; int vis[2000]; int gcd(int a,int b) { return b?gcd(b,a%b):a; } int lcm(int a,int b) { return a/gcd(a,b)*b; } typedef struct good { int c; int d; }; int main() { int n,m; int i,j,k; int fl[MAXN],fr[MAXN]; good p[MAXN]; while(scanf("%d%d",&n,&m)!=EOF) { memset(vis,0,sizeof(vis)); int exit=n+1,enter=0,start=0; for( i=1;i<=n;i++) { fl[i]=fr[i]=i; } for( i=1;i<=m;i++) { scanf("%d %d",&p[i].c,&p[i].d); vis[p[i].c]=1; vis[p[i].d]=1; fl[p[i].d]=p[i].c; fr[p[i].c]=p[i].d; } int flag=0; int ans=0; int L=0,R=0; int last=0; for(i=1;i<=n+1;i++) { if(vis[i]==0) continue; if(flag==0) { flag++; ans+=(i-last); //printf(" %d %d///\n",i,ans); L=i; R=fr[i]; } else if(R<fl[i]) { ans+=(R-L)*3; ans+=(i-R); //flag--; L=fl[i]; R=fr[i]; last=i; //printf("%d %d\n",i,ans); } else if(fl[i]<R&&R<fr[i]) { R=fr[i]; } } //printf("%d\n",ans); ans+=(n+1-R); //printf("%d\n",ans); ans+=(R-L)*3; printf("%d\n",ans); }
D:
题目废话很多,物理公式给了一大堆,题目问的就是有n个障碍,最多反弹b次,在不撞在障碍物的情况下,问最小的初速度是多少
我的想法是枚举次数可以算出每一段长度l=d/(i+1),然后在枚举次数中算出反弹该次数的能越过所有障碍物的最小速度Vy是多少,但这里求得是最小的V。
但是有些细节还是要说一下:可以的到L=2*Vx*Vy,Vx可以由Vy得到,那么只要算出能越过所有的障碍物的Vy就是最小的Vy,由于求的是v=sqrt(Vx*Vx+Vy*Vy),那么当Vx>Vy的时候,Vy可以增大,使得Vx=Vy,此时V是最小的。当Vy>Vx的时候,由于Vy是最小值了,那么就只能按照公式计算速度。
E:
听说DFS,不会做= =
F:
题目意思就是在代价最小的修的桥里面,问有没有不能代替的桥,数量和这些桥的总代价是多少
这就是一道最小生成树判断固定边的问题
http://www.cnblogs.com/clliff/p/4369067.html
G:
是给定一个括号匹配序列,然后每次变换一个括号的方向,然后问把这个括号序列变成匹配,需要变换的最左边的括号是哪一个
题目听起来知道是用线段树,但是自己还没敲出来,敲出来再往上贴