0
点赞
收藏
分享

微信扫一扫

2022-02-16每日刷打卡

奋斗De奶爸 2022-02-16 阅读 61

一、AcWing 338. 计数问题

1. 问题描述

img

2. 问题解决

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 10;

int get(vector<int> num, int l, int r)
{
    int res = 0;
    for (int i = l; i >= r; i -- ) res = res * 10 + num[i];
    return res;
}

int power10(int x)
{
    int res = 1;
    while (x -- ) res *= 10;
    return res;
}

int count(int n, int x)
{
    if (!n) return 0;

    vector<int> num;
    while (n)
    {
        num.push_back(n % 10);
        n /= 10;
    }
    n = num.size();

    int res = 0;
    for (int i = n - 1 - !x; i >= 0; i -- )
    {
        if (i < n - 1)
        {
            res += get(num, n - 1, i + 1) * power10(i);
            if (!x) res -= power10(i);
        }

        if (num[i] == x) res += get(num, i - 1, 0) + 1;
        else if (num[i] > x) res += power10(i);
    }

    return res;
}

int main()
{
    int a, b;
    while (cin >> a >> b , a)
    {
        if (a > b) swap(a, b);

        for (int i = 0; i <= 9; i ++ )
            cout << count(b, i) - count(a - 1, i) << ' ';
        cout << endl;
    }

    return 0;
}

二、AcWing 291. 蒙德里安的梦想

1. 问题描述

img

2. 问题解决

#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long LL;

const int N = 12, M = 1 << N;

int n, m;
LL f[N][M];
vector<int> state[M];
bool st[M];

int main()
{
    while (cin >> n >> m, n || m)
    {
        for (int i = 0; i < 1 << n; i ++ )
        {
            int cnt = 0;
            bool is_valid = true;
            for (int j = 0; j < n; j ++ )
                if (i >> j & 1)
                {
                    if (cnt & 1)
                    {
                        is_valid = false;
                        break;
                    }
                    cnt = 0;
                }
                else cnt ++ ;
            if (cnt & 1) is_valid = false;
            st[i] = is_valid;
        }

        for (int i = 0; i < 1 << n; i ++ )
        {
            state[i].clear();
            for (int j = 0; j < 1 << n; j ++ )
                if ((i & j) == 0 && st[i | j])
                    state[i].push_back(j);
        }

        memset(f, 0, sizeof f);
        f[0][0] = 1;
        for (int i = 1; i <= m; i ++ )
            for (int j = 0; j < 1 << n; j ++ )
                for (auto k : state[j])
                    f[i][j] += f[i - 1][k];

        cout << f[m][0] << endl;
    }

    return 0;
}

三、蓝桥杯十一届 植树

1. 问题描述

img

2. 问题解决

#include<bits/stdc++.h>
using namespace std;
const int N=35;
struct tree
{
    int x,y,r,s;
}; 
bool cross[N][N];

tree t[N];

int maxa,n;

vector<int> plant;

//判断是否相交 
bool judge(tree t1,tree t2)
{
    if(pow(t1.x-t2.x,2)+pow(t1.y-t2.y,2)>= pow(t1.r+t2.r,2)) 
    return false;//不相交 
    return true;//相交 
}

//i表示第i颗树,ans 表示第i颗树未决策时的面积 
void dfs(int i,int ans) 
{
    if(i==n)
    {
        if(ans>maxa) maxa=ans;
        return;
    }
    //判断第i颗树可不可以种
    for(auto j:plant)
    {
        if(judge(t[i],t[j]))
        {
      dfs(i+1,ans);
          return; 
    }
    } 
     
     //如果第i颗树可以种
     //种: 
      plant.push_back(i);
      dfs(i+1,ans+t[i].s);
      plant.pop_back();
      //不种:
      dfs(i+1,ans); 
      return;      
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>t[i].x>>t[i].y>>t[i].r;
        t[i].s=t[i].r*t[i].r;
    } 
    
    for(int i=1;i<n;i++)
    {
        cross[i][i]=true;
        //对称矩阵只用计算一半
        for(int j=0;j<i;j++) 
        {
            cross[i][j]= judge(t[i],t[j]);
            cross[j][i]=cross[i][j];
        }
    } 
    dfs(0,0);
    cout<<maxa;
    return 0;
    
}
举报

相关推荐

0 条评论