训练16

3991: Electoral Rolls Revision

题意:对n对数排序,从小到大输出

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int x=0;
    char c=getchar();
    bool flag=0;
    while(c<'0'||c>'9'){if(c=='-')flag=1;   c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?-x:x;
}
priority_queue<int,vector<int> ,greater<int> > q;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int x=read();
            q.push(x);
        }
    }
     while(!q.empty())
        {
            printf("%d\n",q.top());
            q.pop();
        }
}

//快读+优先队列

4603: Interesting Calculator 

题意:模拟计算器,每个按键有一个花费,问使数x变成数y的最小花费位多少,以及按键次数

#include<bits/stdc++.h>
using namespace std;
int cost[10][3],vis[100005];
struct node{
     int step,cost,num;
     friend bool operator <(const node a,const node b)
     {
         return a.cost>b.cost||(a.cost==b.cost&&a.step>b.step);
     }
}se,ans;
void bfs(int e)
{
    priority_queue<node> q;//优先队列,先优先输出花费较小(花费相同时,步长较小)的元素
    q.push(se);
    memset(vis,0,sizeof(vis));
    while(!q.empty())
    {
        se=q.top();
        q.pop();
        if(vis[se.num])continue;//已经遍历过的数字跳过
        vis[se.num]=1;
        if(se.num==e)
        {
            printf(" %d %d\n",se.cost,se.step);//搜到目标状态直接输出
            return ;
        }
        for(int i=0;i<=2;i++)
        {
            for(int j=0;j<10;j++)
            {
                node temp=se;
                if(i==0)
                {
                    temp.num=temp.num*10+j;
                }
                else if(i==1)
                {
                    temp.num+=j;
                }
                else
                {
                    temp.num*=j;
                }
                if(temp.num<=e)
                {temp.cost+=cost[j][i];
                temp.step++;
                q.push(temp);}
            }
        }//按键模拟,元素入列
    }
}
int main()
{
    int s,e,t=0;
    while(~scanf("%d%d",&s,&e))
    {
        se.step=0;
        se.num=s;
        se.cost=0;
        for(int k=0;k<3;k++)
        for(int i=0;i<=9;i++)
        {
             scanf("%d",&cost[i][k]);
        }//输入按键花费
        ans.cost=0x3f3f3f3f,ans.step=0x3f3f3f3f;
        printf("Case %d:",++t);
        bfs(e);
    }
}

//广搜+优先队列

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100005;
int cost[3][10];
int dis[maxn],num[maxn];//记录到i的最小花费及步长
int vis[maxn];
int s,e;
int Case=1;
void spfa()
{
    memset(dis,INF,sizeof(dis));
    memset(vis,0,sizeof(vis));
    queue<int>q;
    int u,v,t;
    q.push(s);
    num[s]=dis[s]=0;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        for(int i=0;i<3;i++)
            for(int j=0;j<10;j++)
            {
                if(i==0)
                    v=u*10+j;
                else if(i==1)
                    v=u+j;
                else
                    v=u*j;//计算器按键过程模拟
                if(v>e)//v>e表面后续按键过程均无法得到e
                    break;
                if(dis[v]<=dis[u]+cost[i][j])
                    continue;
                dis[v]=dis[u]+cost[i][j];
                num[v]=num[u]+1;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
    }
    printf("Case %d: %d %d\n",Case++,dis[e],num[e]);
}
int main()
{
    while(~scanf("%d%d",&s,&e))
    {
        for(int i=0;i<3;i++)
            for(int j=0;j<10;j++)
                scanf("%d",&cost[i][j]);//记录按键花费
        spfa();
    }
}

//spfa

3407: Parenthesis

题意:删括号,将表达式中可以省略的括号删除

#include<bits/stdc++.h>
using namespace std;
string s;
stack<int> st;
int len;
int check(int l,int r)
{
    int cnt=0;
    for(int i=l;i<=r;i++)
        if(s[i]=='(')
           cnt++;
        else if(s[i]==')')
            cnt--;
        else if(s[i]=='+'&&cnt==0)
        return 0;
      return 1;
}
int main()
{
    while(cin>>s)
    {
        while(1) //每次处理一对括号
        {
           int flag=0;
           len=s.size();
           while(st.size())st.pop();//栈清空
           for(int i=0;i<len;i++)
           {
               if(s[i]=='(')//'('下标入栈
                    st.push(i);
               else if(s[i]==')')
               {
                   int x=st.top();//获得匹配的'(’
                   st.pop();
                   if((x==0||s[x-1]=='+'||s[x-1]=='(')&&(i==len-1||s[i+1]=='+'||s[i+1]==')'))//符合条件 字符串删除括号
                   {
                       s.erase(x,1);
                       s.erase(i-1,1);
                       flag=1;
                       break;
                   }
                   else if(check(x+1,i-1))//上述条件不符合时,查询括号内字符串是否为加分表达式,不是则同样删除括号
                   {
                        s.erase(x,1);
                        s.erase(i-1,1);
                        flag=1;
                        break;
                   }
               }
           }
           if(flag==0) break;//未出现括号多余,表达式符合条件,退出循环
        }
        cout<<s<<endl;
    }
}

//模拟

5971: Cable master

题意:给多条线,需要k条同样长度的线,问可得到线的最大长度

#include<bits/stdc++.h>
using namespace std;
int a[10005],sum;
int n,k;
bool work(int mid)
{
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=a[i]/mid;
    }
    return sum>=k;
}
int main()
{
    while(~scanf("%d %d",&n,&k))
    {
    int right=0,left=1;
    for(int i=1;i<=n;i++)
    {   double x;
        scanf("%lf",&x);
        a[i]=x*100;
        right=max(right,a[i]);
    }
    int ans=0;
    while(left<=right)
    {
        int mid=(left+right)/2;
        if(work(mid))
            left=mid+1,ans=max(ans,mid);
        else
            right=mid-1;
    }
    printf("%.2f\n",ans*1.0/100.0);
    }
}

//二分

4355: Red/Blue Spanning Tree 

题意:给一个无向同图,边分为红蓝两色,问是否能构成最小生成树恰好有k条蓝色边(两点之间最大有一条边)

思路:进行两次最小生成树生成,一次优先红色边得到最小蓝色边数,一次优先蓝色边得到最大蓝色边数,如果k在范围内则存在恰好k条蓝色边的最小生成树

扫描二维码关注公众号,回复: 7965642 查看本文章
#include<bits/stdc++.h>
using namespace std;
struct edge
{
    int x,y,flag;
}e[1005*1005];
int cmp(edge a,edge b)
{
    return a.flag<b.flag;
}
int f[1005],k1,k2;
int find(int x)
{
    return f[x]==-1?x:f[x]=find(f[x]);
}
void Union(edge x,int *p)
{
       int t1=find(x.x);
       int t2=find(x.y);
       if(t1!=t2)
       {
           f[t1]=t2;
           if(x.flag==1)(*p)++;
       }
}
int main()
{
    int n,m,k;
    while(~scanf("%d%d%d",&n,&m,&k),n||m||k)
    {
        char ch;
        int len=0,x,y;
        for(int i=1;i<=m;i++)
        {
            getchar();
            ch=getchar();
            scanf("%d %d",&e[i].x,&e[i].y);
            if(ch=='B')e[i].flag=1;
            else e[i].flag=0;
        }
        sort(e+1,e+m+1,cmp);
        k1=0,k2=0;
        memset(f,-1,sizeof(f));
        for(int i=1;i<=m;i++)
        {
            Union(e[i],&k1);
        }
        memset(f,-1,sizeof(f));
        for(int i=m;i>=1;i--)
        {
            Union(e[i],&k2);
        }
        if(k>=k1&&k2>=k)printf("1\n");
        else printf("0\n");
    }
}

//最小生成树

1589: Six Degrees of Cowvin Bacon

题意:一共有m部电影n头牛,每部电影有一定数量的牛一起合作,规定牛与自身的距离为0,与一起合作过的牛距离为1,与没有一起合作过但是有间接联系(与同一头牛合作过)的牛距离为2,求所有牛与其他牛的最小距离平均值

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int f[305][305],p[305];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
         if(i==j)
         f[i][j]=0;
         else
         f[i][j]=INF;
    }
    for(int i=1;i<=m;i++)
    {   int t;
         scanf("%d",&t);
         for(int j=1;j<=t;j++)
         {
             scanf("%d",&p[j]);
         }
         for(int j=1;j<=t;j++)
         {
             for(int z=j+1;z<=t;z++)
                f[p[j]][p[z]]=f[p[z]][p[j]]=1;
         }
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
           for(int j=1;j<=n;j++)
          {
             f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
          }
          int maxn=INF;
        for(int i=1;i<=n;i++)
        {
             int sum=0;
             for(int j=1;j<=n;j++)
             {
                 sum+=f[i][j];
             }
             maxn=min(maxn,sum);
        }
        printf("%d\n",maxn*100/(n-1));
}

//floyd算法

2200: An Old Stone Game

题意:给一个树,根节点为1 ,有如下规则:

1.玩家可以拥有k个石头,并放入水桶。2.玩家可以从水桶中取一块石头。3.当某一节点的所有r个子节点都放上石头时,玩家可以将r个石头取回,并放放置一个石头在该节点上.4当在根结点上有一颗石头时,玩家胜利

问最少取多少块石头可以取得胜利

#include<bits/stdc++.h>
using namespace std;
vector<int> to[205];
void init()
{
    for(int i=1;i<=200;i++)
        to[i].clear();
}
int cmp(int x,int y)
{
    return x>y;
}
int dfs(int x)
{
     if(!to[x].size())return 1;
     int num[205],maxn=-1;
     for(int i=0;i<to[x].size();i++)
     {
         num[i]=dfs(to[x][i]);
     }
     sort(num,num+to[x].size(),cmp);
     for(int i=0;i<to[x].size();i++)
        maxn=max(maxn,num[i]+i);
     return maxn;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {   int n;
        scanf("%d",&n);
        init();
        for(int i=1;i<=n;i++)
        {   int p,x;
            scanf("%d",&p);
            scanf("%d",&x);
            for(int j=1;j<=x;j++)
            {
                int num;
                scanf("%d",&num);
                to[p].push_back(num);
            }
        }
        cout<<dfs(1)<<endl;
    }
}

//递归

3868: Nearby Cows

题意:有n个牧场,以及m条牧场之间的路,每个牧场都有各自的牛,问每个牧场出发,走k条路以内能到达的牧场的奶牛数量。

#include<bits/stdc++.h>
using namespace std;
const int Max=100005;
struct edge
{
    int to,pos;
}e[Max*2];
int len,f[Max],brother[Max];
int dp[Max][21];//dp[i][j]记录i牧场走j条路的牧场数
void add_edge(int x,int y)
{
    e[++len].to=y;
    e[len].pos=f[x];
    f[x]=len;
}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add_edge(x,y);//存边
        add_edge(y,x);
        brother[x]++;//与x牧场连接的牧场树
        brother[y]++;
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&dp[i][0]);//i牧场自身的奶牛数量
     for(int i=1;i<=k;i++)
        for(int j=1;j<=n;j++)
        {
            for(int z=f[j];z;z=e[z].pos)
                dp[j][i]+=dp[e[z].to][i-1];//dp[j][i]由相连节点的i-1状态相加
            if(i>1)dp[j][i]-=(brother[j]-1)*dp[j][i-2];//去掉重复的
            else dp[j][1]+=dp[j][0];
        }
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",dp[i][k]);
    }
}

//树形DP

猜你喜欢

转载自www.cnblogs.com/llhsbg/p/11925071.html