Loading

蓝桥杯刷题 历届试题 (PREV-1——PREV-10)

PREV-1 核桃的数量

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int a,b,c,d;
    cin>>a>>b>>c;
    d=(a*b/__gcd(a,b));
    cout<<c*d/__gcd(d,c);
}

PREV-2 打印十字图

#include <stdio.h>
 
int a[150][150];
//将这个图划分为多个具有相同规律的部分 然后进行遍历就行
//
int main()
{
    int N;
    int ROW,COL;
    int min;
    int i,j;
    scanf("%d",&N);
    ROW = COL = 9 + (N-1)*4;
    min = ROW / 2;
    for(i = 0; i <= min; i+=2) // 处理上下的 
    {
        for(j = i + 2; j < ROW - (i+2); j++)
        {
            a[i][j] = 1;
            a[ROW - i - 1][j] = 1;
        }
    }
    for(j = 2; j <= min; j+=2) //左右的竖线 
    {
        for(i = j - 2; i < j + 1; i++)
        {
            a[i][j] = 1;
            a[i][COL - j - 1] = 1;
            a[ROW - i - 1][j] = 1;
            a[ROW - i - 1][COL - j - 1] = 1;
         } 
    }
    for(i = 2; i <= min; i += 2)
    {
        for(j = i - 2; j < i + 1; j++)
        {
            a[i][j] = 1;
            a[i][COL - j - 1] = 1;
            a[ROW - i - 1][j] = 1;
            a[ROW - i - 1][COL - j - 1] = 1;
        }
    }
    for(j = 0; j < min; j += 2)//左右长的竖线 
    {
        for(i = j+2; i < ROW - (j + 2); i++)
        {
            a[i][j] = 1;
            a[i][ROW - j - 1] = 1;
        }
    }
    for(i = 0; i < ROW; i++)
    {
        for(j = 0; j < ROW; j++)
        printf("%c", a[i][j] ? '$' : '.');
        putchar('\n');
    }
    return 0;
}

PREV-3 带分数

 dfs求全排列,然后判断这个排列是否能够组成带分数即可

小技巧是不需要完全按照格式模拟,怎么方便怎么求

#include<bits/stdc++.h>

using namespace std;
int s[15],sum=0,t;
void pd()
{
    int a,b,c;
    for(int i=1;i<=9;i++)
    {
        a=0;
        for(int j=1;j<=i;j++)
        {
            a=a*10+s[j];
        }
        if(a<t)
        {
            for(int j=(9-i)/2+i;j<=8;j++)
            {
                b=0;
                c=0;
                for(int h=i+1;h<=j;h++)
                    b=b*10+s[h];
                for(int h=j+1;h<=9;h++)
                    c=c*10+s[h];
                if(b%c==0&&a+b/c==t)
                    sum++;
            }
        }
    }
}

void dfs(int start,int end)
{
    if(start==end)
    {
        pd();
    }
    else
    {
        for(int i=start;i<=end;i++)
        {
            swap(s[i],s[start]);
            dfs(start+1,end);
            swap(s[i],s[start]);
        }
        
    }
}

int main()
{
    cin>>t;
    for(int i=1;i<=9;i++)
    {
        s[i]=i;
    }
    dfs(1,9);
    cout<<sum<<endl;
} 

PREV-4 剪格子

 从左上角dfs即可

#include<bits/stdc++.h>

using namespace std;

int n,m,mp[15][15],sum=0,t=0,f[2][4]={0,0,1,-1,1,-1,0,0},anss=200,vis[15][15];

void dfs(int x,int y,int lsum)
{
    if(lsum==sum/2)
    {
        if(t<anss)
        {
            anss=t;
        }
        return;
    }
    else if(lsum>sum/2)
    {
        return;
    }
    for(int i=0;i<4;i++)
    {
        int xx=x+f[0][i];
        int yy=y+f[1][i];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&vis[xx][yy]==0)
        {
            vis[xx][yy]=1;
            t+=1;
            dfs(xx,yy,lsum+mp[xx][yy]);
            t-=1;
            vis[xx][yy]=0;
        }
    }
}

int main()
{
    cin>>m>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>mp[i][j];
            sum+=mp[i][j]; 
            vis[i][j]=0;
        }
    }
    if(sum%2!=0)
    {
        cout<<'0'<<endl;
        return 0;
    }
    vis[1][1]=1;
    t+=1;
    dfs(1,1,mp[1][1]);
    if(anss==200)
    {
        cout<<0<<endl;
    }
    else
    {
        cout<<anss<<endl;
    }
}

PREV-5 错误票据

#include<bits/stdc++.h>

using namespace std;

map<int,int>mp;
int a[105],n,m,cnt=0,x;

int main()
{
    cin>>n;
    while(scanf("%d",&x)!=EOF)
    {
        if(mp[x]==1)
        {
            n=x;
        }
        else
        {
            a[cnt]=x;
            mp[a[cnt]]=1;
            cnt++;
        }
    }
    sort(a,a+cnt);
    for(int i=1;i<cnt;i++)
    {
        if(a[i]-a[i-1]!=1)
        {
            m=a[i]-1;
        }
    }
    cout<<m<<' '<<n<<endl;
}

PREV-6 翻硬币

 将两个序列不同的位置设为1,相同的设为0,则两个1的下标差为改正这两个位置的最小次数,对于多对1,按顺序遍历即可

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int a[105],anss=0,l=-1;
    string s1,s2;
    cin>>s1>>s2;
    for(int i=0;i<s1.length();i++)
    {
        if(s1[i]!=s2[i])
        a[i]=1;
        else
        a[i]=0;
    }
    for(int i=0;i<s1.length();i++)
    {
        if(a[i]==1)
        {
            if(l==-1)
            {
                l=i;
            }
            else
            {
                anss+=i-l;
                l=-1;
            }
        }
    }
    cout<<anss<<endl;
}

PREV-7 连号区间数

 如果区间两端下标的差正好等于区间最大值-最小值,那么为连续区间

#include<bits/stdc++.h>

using namespace std;

int n,a[50005],s[50005],anss=0,i,l,r;

int main()
{
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin>>a[i];
        s[i]=1;
    }
    for(l=0;l<n;l++)
    {
        int maxn=a[l];
        int minn=a[l];
        for(r=l+1;r<n;r++)
        {
            maxn=max(maxn,a[r]);
            minn=min(minn,a[r]);
            if(maxn-minn==r-l)
            s[l]++;
        }
        anss+=s[l];
    }
    cout<<anss<<endl;
}

PREV-8 买不到的数目

 动态规划,遍历的最大边界是两个数的最小公倍数

#include<bits/stdc++.h>

using namespace std;
int n,m,vis[1000005],anss=1,maxn;
int main()
{

    cin>>n>>m;
    maxn=n*m/__gcd(n,m);
    memset(vis,0,sizeof(vis));
    vis[n]=1;
    vis[m]=1;
    for(int i=1;i<maxn;i++)
    {
        if(vis[i])
        {
            vis[i+n]=1;
            vis[i+m]=1;
        }
        else
        {
            anss=i;
        }
    }
    cout<<anss<<endl;
}

PREV-9 大臣的旅费

 求树的直径,只需进行两次bfs,一次bfs找到直径的一个端点,第二次bfs从这个端点出发,找到对应的另个端点

 

#include<bits/stdc++.h>

using namespace std;

queue<int>q;
vector<int>lb[10005];
int mp[10005][10005],vis[10005],a,b,x,n,anss=0,end,end2;

int getlong(int x)
{
    int sum=0;
    for(int i=1;i<=x;i++)
    {
        sum+=i+10;
    }
    return sum;
}

void bfs()
{
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        int step = q.front();
        q.pop();
        vis[now]=1;
        if(anss<step)
        {
            end=now;
            anss=step;
        }
        for(int i=0;i<lb[now].size();i++)
        {
            if(vis[lb[now][i]]==0)
            {
                q.push(lb[now][i]);
                q.push(step+mp[lb[now][i]][now]);
            }
        }
    } 
}

void bfs2()
{
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        int step = q.front();
        q.pop();
        vis[now]=1;
        if(anss<step)
        {
            end2=now;
            anss=step;
        }
        for(int i=0;i<lb[now].size();i++)
        {
            if(vis[lb[now][i]]==0)
            {
                q.push(lb[now][i]);
                q.push(step+mp[lb[now][i]][now]);
            }
        }
    } 
}

int main()
{
    cin>>n;
    for(int i=1;i<n;i++)
    {
        cin>>a>>b>>x;
        mp[a][b]=x;
        mp[b][a]=x;
        vis[a]=0;
        vis[b]=0;
        lb[a].push_back(b);
        lb[b].push_back(a);
    }
    q.push(1);
    q.push(0);
    bfs();
    memset(vis,0,sizeof(vis));
    //cout<<end<<endl;
    anss=0;
    q.push(end);
    q.push(0);
    bfs2();
    cout<<getlong(anss)<<endl;
    //cout<<end2<<endl;
}

PREV-10 幸运数

 直接暴力模拟,没想到就能过

#include<bits/stdc++.h>

using namespace std;
int n,m,lists[1000005],sum,cnt,i,start,fm,anss=0;
int main()
{
    cin>>m>>n;
    start = 2;
    sum=2*n;
    for(i=1;i<=2*n;i++)
    {
        //alive[i]=1;
        lists[i]=i;
    }
    while(1)
    {
        fm=lists[start];
        if(fm>=n)
        break;
        cnt=0;
        for(i=0;i<start;i++)
        {
            lists[cnt++]=lists[i];
        }
        for(i=start;i<sum;i++)
        {
            if(i%fm==0)
                continue;
            else
                lists[cnt++]=lists[i];
        }
        sum = cnt; 
        start++;
        if(fm==2)
        start--;
    } 
    for(i=1;i<sum;i++)
    {
        if(lists[i]>m&&lists[i]<n)
        anss++;
        if(lists[i]>=lists[i+1])
        break; 
    }
    cout<<anss<<endl;
}

 

posted @ 2020-10-15 01:28  dyhaohaoxuexi  阅读(116)  评论(0编辑  收藏  举报