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

 

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);
    }
 
View Code

 

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:

是给定一个括号匹配序列,然后每次变换一个括号的方向,然后问把这个括号序列变成匹配,需要变换的最左边的括号是哪一个

题目听起来知道是用线段树,但是自己还没敲出来,敲出来再往上贴

 

posted @ 2015-03-29 16:19  Cliff Chen  阅读(170)  评论(0编辑  收藏  举报