day 20 暴力枚举

P3392 涂国旗

涂最少的格子(枚举)

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

int n, m, ans = 1e9;
char a[55][55];

int main()
{
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
            cin >> a[i][j];
//枚举白蓝分界线和蓝红分界线位置
    for(int i = 0; i < n - 2; i++){//最后两行不可能为白色
        for(int j = i + 1; j < n - 1; j++){//至少最后一行为红色 
            int t = 0;
            for(int k = 0; k <= i; k++)//前i行白 
                for(int l = 0; l < m; l++) if(a[k][l] != 'W') t++;
            for(int k = i + 1; k <= j; k++)//i到j蓝色 
                for(int l = 0; l < m; l++) if(a[k][l] != 'B') t++;
            for(int k = j + 1; k < n; k++)//后几行红色 
                for(int l = 0; l < m; l++) if(a[k][l] != 'R') t++;
            ans = min(ans, t);         
        } 
    }
    cout << ans << endl; 
    return 0;
}

P3654 First Step (ファーストステップ)

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

int r, c, k, ans, tx, ty;
char m[105][105];
void dfs(int x, int y, int num, int tf){
    if(num == k){ans++; return;};
    if(tf == 0){//横着 
        tx = x + 1;
        if(m[tx][y] == '.') dfs(tx, y, num + 1, 0);
    }
    if(tf == 1){//竖着 
        ty = y + 1;
        if(m[x][ty] == '.') dfs(x, ty, num + 1, 1);
    }
}
int main()
{
    cin >> r >> c >> k;
    memset(m, '#', sizeof(m));
    for(int i = 1; i <= r; i++)
        for(int j = 1; j <= c; j++)
            cin >> m[i][j];
    for(int i = 1; i <= r; i++){
        for(int j = 1; j <= c; j++){
            if(m[i][j] == '.'){
                dfs(i, j, 1, 0);//f=0:横着
                dfs(i, j, 1, 1);//f=1:竖着 
            }
5        }
    }
    if(k == 1) cout << ans / 2 << endl;//k==1时,横竖都一样 
    else cout << ans << endl; 
    return 0;
}

P1217 [USACO1.5]回文质数 Prime Palindromes

最大的回文质数是9989899;

提示 1: 找出所有的回文数再判断它们是不是质数(素数);

i%2==1时,i+奇数一定为2的倍数,因此循环可以i+=2;

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

int a, b;
bool isprime(int n){
    if(n == 2 || n == 3) return true;
    else if(n % 6 != 1 && n % 6 != 5) return false;
    else{
        for(int i = 5; i * i <= n; i += 6)
            if(!(n % i)||!(n % (i+2))) return false;
        return true; 
    }
}
bool check(int n){//判断素数
    int t = n, sum = 0;
    while(t){
        sum = sum * 10 + t % 10;
        t /= 10;
    }
    if(sum == n) return true;
    else return false;
}
int main()
{
    cin >> a >> b;
    if(b >= 9989899) b = 9989899;
    if(a % 2 == 0) a++;
    for(int i = a; i <= b; i += 2){
        if(check(i) == 0) continue;
        else if(isprime(i)) cout << i << endl; 
    }
    return 0;
}

P1149 [NOIP2008 提高组] 火柴棒等式

  1. 加号与等号各自需要两根火柴棍;

  1. 如果 A !=B,则 A+B=C 与 B+A=C 视为不同的等式(A,B,C≥0);

  1. n 根火柴棍必须全部用上。

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

int n, num[10]={6, 2, 5, 5, 4, 5, 6, 3, 7, 6}, ans;
int fun(int n){
    int sum = 0, i;
    for(i = n; i != 0; i /= 10)
        sum += num[i % 10];
    if(n == 0) sum += num[0];
    return sum;
}
int main()
{
    cin >> n;
    for(int i = 0; i <= 1000; i++)
        for(int j = 0; j <= 1000; j++)
            if(fun(i) + fun(j) + fun(i + j) + 4 == n) ans ++;
    cout << ans << endl;
    return 0;
}

P3799 妖梦拼木棒

设四个木棒长度分别为 a,b,c,d不妨设 abcd

当 a+b=c=d 的时候才能够拼成等边三角形。

即,只有四个木棒的长度分别为 a,b,a+b 和 a+b 的时候才能拼成一个等边三角形。

枚举 a,b 确定长度为 a+b 的木棒的数量numa,numb,numab

①当 a≠b时,ans += numa * numb * numab

②当 a=b时,ans += numa * (numa - 1) * numab

设a<=b, 避免重复

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

ll n, a[100005], num[100005], ans;
ll mod = 1e9 + 7, maxa = -1;
ll C2(int n){return (n * (n - 1) / 2) % mod; }//Cn2
int main()
{
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        maxa = max(maxa, a[i]);
        num[a[i]]++;
    }//枚举a, b
    for(int i = 1; i <= maxa; i++){
        for(int j = i; j <= maxa; j++){// b >= a
            if(i == j) ans = (ans + C2(num[i]) * C2(num[i + j])) % mod; 
            else ans = (ans + ((num[i] * num[j]) % mod * C2(num[i + j])) % mod) % mod;
        }
    } cout << ans << endl;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值