首页 > 其他 > 详细

训练8

时间:2019-11-04 00:14:43      阅读:88      评论:0      收藏:0      [点我收藏+]

2790: Dominos 2

题意:多米诺骨牌,求有多少骨牌会被推掉

#include<bits/stdc++.h>
using namespace std;
vector<int> v[10005];
int vis[10005],num;
void dfs(int z)
{
    vis[z]=1;
    num++;
    for(int i=0;i<v[z].size();i++)
    {
        if(vis[v[z][i]]==0)
        {
            dfs(v[z][i]);
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m,l;
        memset(vis,0,sizeof(vis));
        scanf("%d%d%d",&n,&m,&l);
        for(int i=0;i<=n;i++)
        {
            v[i].clear();
        }
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
        }
        num=0;
        for(int i=1;i<=l;i++)
        {   int z;
            scanf("%d",&z);
            if(vis[z]==0)dfs(z);
        }
        printf("%d\n",num);
    }
}

//深搜

6061: Bomb

题意:给一个数n,求1~n中包含49的数的个数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll d;
ll dp[25][3];
void init()
{
    dp[0][0]=1;//dp[i][0]表示i位数内不含49的个数
    dp[0][1]=dp[0][2]=0;//dp[i][1]表示i位数内以9为首的不含49的个数
    for(int i=1;i<20;i++) //dp[i][2]表示i位数内含49的个数
    {
        dp[i][0]=10*dp[i-1][0]-dp[i-1][1];
        dp[i][1]=dp[i-1][0];
        dp[i][2]=10*dp[i-1][2]+dp[i-1][1];
    }
}
ll check(ll d)
{
     int num[25]={0},len=0;
     while(d>0)
     {
         num[++len]=d%10;
         d/=10;
     }
     ll sum=0;
     int flag=0;
     for(int i=len;i>=1;i--)//逐位添加
     {
         sum+=dp[i-1][2]*num[i];
         if(flag)
         sum+=dp[i-1][0]*num[i];
         else
         {
             if(num[i]>4)sum+=dp[i-1][1];
         }
         if(num[i+1]==4&&num[i]==9)flag=1;
     }
     if(flag)sum++;
     return sum;
}
int main()
{
    int t;
    init();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld",&d);
        printf("%lld\n",check(d));
    }
}

//数位dp

6067: LCM Walk

题意:从起点(x,y)开始可向上或者向右移动lcm(x,y)步,现在给出一个终点,求有多少个点作为起点可到达该终点

思路:设起点为(qt,pt),t为最小公因数,最小公倍数为qpt,故终点为(qt,pt+qpt)--->(qt,(1+q)pt), 因此可逆推出 终点(x,y),x<y时,若y%(x+1)==0则有一个点可作为起始点

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        long long  a,b,num=1;
        scanf("%lld%lld",&a,&b);
        printf("Case #%d: ",i);
        int d=__gcd(a,b);
        a/=d;
        b/=d;
        while(1)
        {
           if(a>b)swap(a,b);
           if(b%(a+1))
                break;
           b=b/(a+1);
           num++;
        }
        printf("%lld\n",num);
    }
}

//逆推

6072: sum

题意:求一个序列的连续子序列之和能否被m整除

#include<bits/stdc++.h>
using namespace std;
int num[5005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {   int n,m;
        scanf("%d%d",&n,&m);
        int flag=0,sum=0;
        memset(num,0,sizeof(num));
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            sum+=x;
            if(sum%m==0)flag=1;//前缀和被m整除
            if(num[sum%m]==1)flag=1;//当序列的前缀和出现两次除m余数相同时,说明,连续子序列和存在被m整除的情况
            num[sum%m]++;
        }
        if(flag)printf("YES\n");
        else
        printf("NO\n");
    }
}

 

6074: Shopping

题意:先给出n个店的店名,再给出m个n行,每行为涨价值以及对应的店名,求memory店铺的商品价值在所有店铺商品价值的排名

#include<bits/stdc++.h>
using namespace std;
map<string,int> m;
int money[10005];
int main()
{
    int n,t,flag;
    scanf("%d",&n);
    getchar();
    for(int i=1;i<=n;i++)
    {
        string s;
        char ch;
        while(ch=getchar())
        {
            if(ch==\n)break;
            s+=ch;
        }
        m[s]=i;
        if(s=="memory")
            flag=i;
    }
    scanf("%d",&t);
    while(t--)
    {
        for(int i=1;i<=n;i++)
        {
            int in;
            scanf("%d",&in);
            string s;
            char ch;
           getchar();
           while(ch=getchar())
           {
            if(ch==\n)break;
            s+=ch;
           }
            money[m[s]]+=in;
        }
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            if(money[i]>money[flag])sum++;
        }
        printf("%d\n",sum+1);
    }
}

//map容器

6083: Rank of Tetris

题意:"A > B","A = B","A < B"根据这三类信息判断信息是冲突,是否完整。 

#include<bits/stdc++.h>
using namespace std;
int x[20005],y[20005],f[10005],in[20005];
vector<int> vec[10005];
char ch[20005];
int n,m;
int find(int x)
{
    return f[x]==x?x:find(f[x]);
}
void work()
{
    queue<int> q;
    int num=0,ans=0;
    for(int i=1;i<=n;i++)
    {
        int t1=find(i);
        if(t1==i)
        {
           if(in[t1]==0)
           q.push(t1);//添加0入度点进入队列
           num++;//记录点数
        }
    }
    int flag=0;
    while(q.size())
    {
        if(q.size()>1)//队列出现超过一个元素,说明信息不完整,有至少一对点的大小关系不能确定
        {
            flag=1;
        }
        int z=q.front();
        q.pop();
        ans++;
        for(int i=0;i<vec[z].size();i++)
        {
            int t1=find(vec[z][i]);
            in[t1]--;
            if(in[t1]==0)q.push(t1);
        }
    }
    if(ans!=num)
        printf("CONFLICT\n");
    else
    {
        if(flag)
        printf("UNCERTAIN\n");
        else
        printf("OK\n");
    }
}

//并查集+拓扑排序

训练8

原文:https://www.cnblogs.com/llhsbg/p/11789493.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!