0
点赞
收藏
分享

微信扫一扫

13~18年蓝桥杯c++B组省赛真题

钎探穗 2022-03-31 阅读 42
c++

2013蓝桥杯省赛

1.高斯日记 日期 1799-07-16

#include <cstdio>
#include <iostream>
using namespace std;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool valid(int date) {
	int year = date / 10000;
	int month = date % 10000 / 100;
	int day = date % 100;
	if (month == 0 || month > 12) return false;
	if (day == 0 || month != 2 && day > days[month]) return false;
	if (month == 2) {
		int leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
		if (day > 28 + leap) return false;
	}
	return true;
}
int main() {
	int n = 8113, cnt = 0;
	for (int i = 17770430; i <= 19999999; i ++ ) {
		if (valid(i)) {
			cnt ++ ;
			if (cnt == n) {
				printf("%d-%02d-%02d\n", i / 10000, i % 10000 / 100, i % 100);
				break;
			}
		}
	} 
	return 0;
}

2.马虎的算式 142

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20;
int a[N];
int cnt;
int main() {
	int n = 9;
	for (int i = 1; i <= n; i ++ ) {
		a[i] = i;
	}
	do {
		if ((a[1] * 10 + a[2]) * (a[3] * 100 + a[4] * 10 + a[5]) == 
		(a[1] * 100 + a[4] * 10 + a[2]) * (a[3] * 10 + a[5])) {
			cnt ++ ;
		}
	} while (next_permutation(a + 1, a + n + 1));
	printf("%d\n", cnt / 24);
	return 0;
}

3.第39级台阶 51167078

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int ans;
void f(int n, int step) {
	if (n < 0) return;
	if (n == 0 && step % 2 == 0) {
		ans ++ ;
		return;
	}
	f(n - 1, step + 1);
	f(n - 2, step + 1);
}
int main() {
	f(39, 0);
	printf("%d\n", ans);
	return 0;
}

4.黄金连分数

#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>

using namespace std;

int n = 400;


void i2s(int num, string &str) {
    stringstream ss;
    ss << num;
    ss >> str;
}

string add(string a, string b) {
    a = a.substr(a.find_first_not_of('0'));
    b = b.substr(b.find_first_not_of('0'));
    long long lenA = a.length();
    long long lenB = b.length();
    long long len = max(lenA, lenB) + 10;
//翻转,便于从低位逐步求和
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());

    string ans(len, '0');//初始化答案为len长,全部为字符0
//    把a拷贝到ans中
    for (int i = 0; i < lenA; ++i) {
        ans[i] = a[i];
    }
    int tmp = 0;//tmp是上一位相加后的进位
    for (int i = 0; i < len; ++i) {
        if (i < b.length())
            tmp += (ans[i] - '0') + (b[i] - '0');//假设为18
        else
            tmp += (ans[i] - '0');
        ans[i] = tmp % 10 + '0';//8 8+'0'
        tmp /= 10;//1
    }
    reverse(ans.begin(), ans.end());
    return ans.substr(ans.find_first_not_of('0'));
}

int cmp(string a, string b) {
    unsigned long i1 = a.find_first_not_of('0');
    if (i1 == string::npos)a = '0';
    else a.substr(i1);

    unsigned long i2 = b.find_first_not_of('0');
    if (i2 == string::npos)b = '0';
    else b.substr(i2);

    if (a.length() > b.length())return 1;
    else if (a.length() < b.length())return -1;
    else {//长度相等
        if (a < b)return -1;
        if (a > b)return 1;
        else return 0;
    }
}

//此处,a一定大于等于b
string subtract(string a, string b) {
//    完整的减法里面,a可以小于b,这时结果为负数,交换ab进行下面的代码
//    1.翻转
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
//    2.按位做减法
    for (int i = 0; i < b.length(); ++i) {
        if (a[i] >= b[i]) {
            a[i] = a[i] - b[i] + '0';
        } else {//就要借
            int k = 1;
            while (a[i + k] == '0') {
                a[i + k] = '9';
                k++;
            }
//            这里可以保证i+k这一位上不是0
            a[i + k] = a[i + k] - '1' + '0';

            a[i] = (a[i] - '0' + 10) - (b[i] - '0') + '0';
        }
    }

    reverse(a.begin(), a.end());
    if (a.find_first_not_of('0') == string::npos)return "0";
    return a.substr(a.find_first_not_of('0'));
}

/*转换成减法*/
string divide(string a, string b) {
//    只考虑a<b的情况
    string ans = "0.";
//    转化成减法
    for (int i = 0; i < 101; ++i) {//101次
        a.append("0");
        int t = 0;
        while (cmp(a, b) >= 0) {//a>=b
            a = subtract(a, b);//不停地做减法
            t++;//记录减法做了多少次
        }
        string t_str;
        i2s(t, t_str);
        ans.append(t_str);
    }
    return ans;
}

int main(int argc, const char *argv[]) {
    string a = "1";
    string b = "1";
    cout << subtract(a, b) << endl;
    for (int i = 3; i <= n; ++i) {
        string tmp = b;
        b = add(a, b);
        a = tmp;
//        cout << b << " " << endl;
    }
//    a b是斐波那契的n-1和n项
    string ans = divide(a, b);
    cout << ans << endl;
    cout << ans.length()-2 << endl;
    return 0;
}
#include <iostream>
using namespace std;
int main()
{
  string ans = "0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375";
  cout << ans << endl;
  return 0;
}

5.前缀判断

#include <iostream>

using namespace std;

/**
 *
 * @param haystack_start 母串
 * @param needle_start 前缀
 * @return
 */
char *prefix(char *haystack_start, char *needle_start) {
    char *haystack = haystack_start;
    char *needle = needle_start;//前缀


    while (*haystack && *needle) {//两个指针都没有越界
//        if(______________________________) return NULL;  //填空位置
//移动指针
//并判断
        if (*(haystack++) != *(needle++))return NULL;
    }

    if (*needle) return NULL;

    return haystack_start;
}

int main(int argc, const char *argv[]) {
    cout << prefix("abcd123", "abd") << endl;
    return 0;
}

6.三步排序

#include <iostream>
using namespace std;
void sort3p(int* x, int len)
{
    int mod = 0;
    int left = 0;
    int right = len-1;

    while(mod<=right){
        if(x[mod]<0){
            int t = x[left];
            x[left] = x[mod];
            x[mod] = t;
            left++;
            mod++;
        }
        else if(x[mod]>0){
            int t = x[right];
            x[right] = x[mod];
            x[mod] = t;
            right--;
        }
        else{//==0
//            __________________________;  //填空位置
            mod++;
        }
    }

}

int main(int argc, const char * argv[]) {
    int arr[]={25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
    sort3p(arr,14);
    for (int i = 0; i < 14; ++i) {
        cout<<arr[i]<<" ";
    }
    return 0;
}

7.错误票据

#include <iostream>
#include <sstream>
#include <algorithm>

using namespace std;
const int MaxN = 10000;
int line;
int data[MaxN];

void s2i(string &str, int &num) {
    stringstream ss;
    ss << str;
    ss >> num;
}

int main(int argc, const char *argv[]) {
    scanf("%d", &line);
    getchar();
    int index = 0;
    for (int i = 0; i < line; ++i) {
        string s;
        getline(cin, s);
        istringstream iss(s);
        string tmp;
        while (getline(iss, tmp, ' ')) {
            s2i(tmp, data[index++]);
        }
    }
//    最终index就是数据的个数
//    cout << index << endl;
//排序
    sort(data, data + index);
    int a, b;
    for (int i = 1; i < index; ++i) {
        if (data[i] == data[i - 1] + 2)a = data[i] - 1;//printf("%d ", data[i] - 1);
        if (data[i] == data[i - 1]) b = data[i];//printf("%d", data[i]);
    }
    printf("%d %d", a, b);
    return 0;
}
#include <iostream>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;
const int N = 10010;
int n;
int a[N];
int main() {
    int cnt;
    scanf("%d", &cnt);
    string line;
    getline(cin, line);
    while (cnt -- ) {
        getline(cin, line);
        stringstream ssin(line);
        while (ssin >> a[n]) n ++ ;
    }
    sort(a, a + n);
    int res1, res2;
    for (int i = 1; i < n; i ++ )
        if (a[i] == a[i - 1]) res2 = a[i];
        else if (a[i] >= a[i - 1] + 2) res1 = a[i] - 1;
    printf("%d %d", res1, res2);
    return 0;
}

8.翻硬币

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char a[110], b[110];
int n, ans;
void turn(int i) {
    if (a[i] == 'o') a[i] = '*';
    else a[i] = 'o';
}
int main() {
    scanf("%s %s", a, b);
    n = strlen(a);
    for (int i = 0; i + 1 < n; i ++ ) {
        if (a[i] != b[i]) {
            turn(i), turn(i + 1);
            ans ++;
        }
    }
    printf("%d\n", ans);
    return 0;
}

9.带分数

next_permutation全排列,枚举,爆搜

#include <iostream>
#include <algorithm>
using namespace std;
int a[10];
int x;
int res;
int pow(int a, int n) {
    int res = a;
    for (int i = 1; i <= n; i ++ ) {
        res *= 10;
    }
    return res;
}
int temp(int l, int r) {
    int ans = 0;
    for (int i = l; i <= r; i ++ ) {
        ans += pow(a[i], r - i);
    } 
    return ans;
}
int main() {
    scanf("%d", &x);
    for (int i = 1; i <= 9; i ++ ) {
        a[i] = i;
    }
    do {
        for (int i = 1; i <= 7; i ++ ) {
            for (int j = i + 1; j <= 8; j ++ ) {
            	int x1 = temp(1, i), x2 = temp(i + 1, j), x3 = temp(j + 1, 9);
            	if (x * x3 == x1 * x3 + x2) res ++ ;
            }
        }
    } while (next_permutation(a + 1, a + 10));
    printf("%d", res);
    return 0;
}

y总双层 dfs_c dfs_a

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 10;

int n;
bool st[N], backup[N];
int ans;

bool check(int a, int c) {
    long long b = n * (long long)c - a * c;
    if (!a || !b || !c) return false;
    memcpy(backup, st, sizeof st);
    while (b) {
        int x = b % 10;
        b /= 10;
        if (!x || backup[x]) return false;
        backup[x] = true;
    }
    for (int i = 1; i <= 9; i ++ ) {
        if (!backup[i])
            return false;
    }
    return true;
}

void dfs_c(int u, int a, int c) {
    if (u > 9) return;
    if (check(a, c)) ans ++ ;
    for (int i = 1; i <= 9; i ++ ) {
        if (!st[i]) {
            st[i] = true;
            dfs_c(u + 1, a, c * 10 + i);
            st[i] = false;
        }
    }
}

void dfs_a(int u, int a) {
    if (a >= n) return;
    if (a) dfs_c(u, a, 0);
    for (int i = 1; i <= 9; i ++ ) {
        if  (!st[i]) {
            st[i] = true;
            dfs_a(u + 1, a * 10 + i);
            st[i] = false;
        }
    }
}
int main() {
    scanf("%d", &n);
    dfs_a(0, 0);
    printf("%d\n", ans);
    return 0;
}

10.连号区间数

#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010, INF = 100000000;
int n;
int a[N];
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    int res = 0;
    for (int i = 0; i < n; i ++ ) {
        int minv = INF, maxv = -INF;
        for (int j = i; j < n; j ++ ) {
            minv = min(minv, a[j]);
            maxv = max(maxv, a[j]);
            if (maxv - minv == j - i) res ++ ;
        }
    }
    printf("%d\n", res);
    return 0;
}

2014蓝桥杯省赛

1.啤酒和饮料 11

#include <cstdio>
#include <cstdlib>
#include <iostream> 
using namespace std;
int main() {
	int sum = 0, target = 82.3;
	for (int i = 1; i <= 40; i ++ ) {
		for (int j = i + 1; j <= 40; j ++ ) {
			if (i * 2.3 + j * 1.9 == target) {
				sum = i;
			}
		}
	}
	cout << 11 * 2.3 + 30 * 1.9 << endl;
	printf("%d", sum);
	return 0;
}

2.切面条 2^n + 1 1025

#include <cstdio>
int main() {
    printf("%d", (1 << 10) + 1);
    return 0;
}

3.李白打酒 14

dfs if (花 > 0) dfs(下一状态)

​ if (店 > 0) dfs(下一节点)

#include <cstdio>
int ans;
//babaabbabbabbbb a:*2 b:-1 a5 b10
//babaabbabbabbb			a5 b9
void f(int dian, int hua, int u) {
	// if (dian < 0 || hua < 0) return;
	if (u == 1 && dian == 0 && hua == 0) {
		ans ++ ;
		return;
	}
	if (dian > 0) f(dian - 1, hua, u * 2);
	if (hua > 0) f(dian, hua - 1, u - 1);
}
int main() {
	f(5, 9, 2);
    printf("%d", ans);
    return 0;
}

4.史丰收速算

if(tr>0) return i;

#include <iostream>
using namespace std;
//计算个位
int ge_wei(int a)
{
    if(a % 2 == 0)//偶数
        return (a * 2) % 10;//乘以2保留个位
    else
        return (a * 2 + 5) % 10;//奇数,乘以2加上5,保留个位
}

//计算进位
int jin_wei(char* mod)
{
    char* level[] = {
            "142857",
            "285714",
            "428571",
            "571428",
            "714285",
            "857142"
    };//多位数超过 n/7,就要进n

    char buf[7];
    buf[6] = '\0';
    strncpy(buf,mod,6);//将mod这个字符串的前6个字符,拷贝到buff中

    int i;
    for(i=5; i>=0; i--){
        int tr = strcmp(level[i], buf);//从后往前,依次level中的串和buff比较
        if(tr<0)//buff更大 ,得出了进位数=i+1
            return i+1;
        while(tr==0){//buff和level[i]相同了
            mod += 6;//往后偏移6位
            strncpy(buf,mod,6);//再拷贝6个字符到buff中
            tr = strcmp(level[i], buf);//再比较
            if(tr<0) return i+1;//buf更大
//            ______________________________;  //填空
//            //?//buff更小
            if(tr>0)  return i;

        }
    }

    return 0;
}

//多位数乘以7
void f(char* s)//s代表多位数
{
    int head = jin_wei(s);//head是s的进位
    if(head > 0) printf("%d", head);//输出进位

    char* mod = s;//拷贝字符串指针
    while(*mod){//没有到末尾
        int a = (*mod-'0');//依次字符转数字
        int ge = ge_wei(a);//算出个位
        int jin = jin_wei(mod + 1);//后续字符串的进位
        int x = (ge + jin) % 10;//两者相加取个位
        printf("%d",x);//打印
        mod++;//指针后移
    }

    printf("\n");
}

int main()
{
    f("4285711");
    f("34553834937543");
    return 0;
}

5.打印图形

#include <iostream>

using namespace std;
#define N 70

void f(char a[][N], int rank, int row, int col) {
    if (rank == 1) {
        a[row][col] = '*';
        return;
    }

    int w = 1;
    int i;
    for (i = 0; i < rank - 1; i++)
        w *= 2;

//    ____________________________________________;
    f(a, rank - 1, row , col+w/2);//a,5,0,16,处理顶上的三角形
    f(a, rank - 1, row + w / 2, col);//a,5,16,0,处理左下角
    f(a, rank - 1, row + w / 2, col + w);//a,5,16,16,处理右下角
}

int main() {
    char a[N][N];
    int i, j;
    for (i = 0; i < N; i++)
        for (j = 0; j < N; j++) a[i][j] = ' ';

    f(a, 5, 0, 0);

    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) printf("%c", a[i][j]);
        printf("\n");
    }

    return 0;
}

6.奇怪的分式 14

#include <cstdio>
int ans;
// i/j k/m
// i * k * (j * 10 + m) == j * m * (i * 10 + k)
int main() {
	for (int i = 1; i <= 9; i ++ ) {
		for (int j = 1; j <= 9; j ++ ) {
			for (int k = 1; k <= 9; k ++ ) {
				for (int m = 1; m <= 9; m ++ ) {
					if (i * k * (j * 10 + m) == j * m * (i * 10 + k)) {
						if (i != j && k != m) {
							//printf("%d %d %d %d\n", i, j, k, m);
							ans ++ ;
						}
					}
				}
			}
		}
	}
	printf("%d", ans);
    return 0;
}

7.六角填数 暴力枚举 1~12 next_permutation

/* 9 2 7 10 12 6 5 4 11 0~9 填上没有的数  */
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void check(vector<int> v);

int main(int argc, const char *argv[]) {
    vector<int> v;
    v.push_back(2);
    for (int i = 4; i <= 7; ++i) {
        v.push_back(i);
    }
    for (int i = 9; i <= 12; ++i) {
        v.push_back(i);
    }

    do {
        check(v);
    } while (next_permutation(v.begin(), v.end()));

    return 0;
}

void check(vector<int> v) {
    int r1 = 1 + v[0] + v[3] + v[5];
    int r2 = 1 + v[1] + v[4] + v[8];
    int r3 = 8 + v[0] + v[1] + v[2];
    int r4 = 11 + v[3] + v[6];
    int r5 = 3 + v[2] + v[4] + v[7];
    int r6 = v[5] + v[6] + v[7] + v[8];

    if (r1 == r2 && r2 == r3 && r3 == r4 && r4 == r5 && r5 == r6) {
        for (int i = 0; i < 9; ++i) {
            cout << v[i] << " " << endl;
        }
    }
}

8.蚂蚁感冒

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

using namespace std;

const int N = 55;

int n;
int x[N];

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &x[i]);
    
    int left = 0, right = 0;
    for (int i = 1; i < n; i ++ ) {
        if (abs(x[i]) < abs(x[0]) && x[i] > 0) left ++ ;
        else if (abs(x[i]) > abs(x[0]) && x[i] < 0) right ++ ;
    }
    if (x[0] > 0 && right == 0 || x[0] < 0 && left == 0) printf("%d\n", 1);
    else printf("%d\n", left + right + 1);
    return 0;
}

9.地宫取宝

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

using namespace std;

const int N = 55, MOD = 1000000007;

int n, m, k;
int w[N][N];
int f[N][N][13][14];

int main() {
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) {
            scanf("%d", &w[i][j]);
            w[i][j] ++ ;
        }
    }
    f[1][1][1][w[1][1]] = 1;
    f[1][1][0][0] = 1;
    
    for (int i = 1; i <= n; i ++ ) {
        for (int j = 1; j <= m; j ++ ) {
            if (i == 1 && j == 1) continue;
            for (int u = 0; u <= k; u ++ ) {
                for (int v = 0; v <= 13; v ++ ) {
                    int &val = f[i][j][u][v];
                    val = (val + f[i - 1][j][u][v]) % MOD;
                    val = (val + f[i][j - 1][u][v]) % MOD;
                    if (u > 0 && v == w[i][j]) {
                        for (int c = 0; c < v; c ++ ) {
                            val = (val + f[i - 1][j][u - 1][c]) % MOD;
                            val = (val + f[i][j - 1][u - 1][c]) % MOD;
                        }
                    }
                }
            }
        }
    }
    int res = 0;
    for (int i = 0; i <= 13; i ++ ) res = (res + f[n][m][k][i]) % MOD;
    
    printf("%d\n", res);
    return 0;
}

10.小朋友排队

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 1000010;

int n;
int h[N], tr[N];
int sum[N];

int lowbit(int x) {
    return x & -x;
}

void add(int x, int v) {
    for (int i = x; i < N; i += lowbit(i)) tr[i] += v;
}

int query(int x) {
    int res = 0;
    for (int i = x; i; i -= lowbit(i)) res += tr[i];
    return res;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &h[i]), h[i] ++ ;
    for (int i = 0; i < n; i ++ ) {
        sum[i] = query(N - 1) - query(h[i]);
        add(h[i], 1);
    }
    memset(tr, 0, sizeof tr);
    for (int i = n - 1; i >= 0; i -- ) {
        sum[i] += query(h[i] - 1);
        add(h[i], 1);
    }
    
    LL res = 0;
    for (int i = 0; i < n; i ++ ) res += (LL)sum[i] * (sum[i] + 1) / 2;
    cout << res << endl;
    return 0;
}

2015蓝桥杯省赛

1.奖券数目 52488

#include <cstdio>
int ans;
int main() {
	for (int i = 10000; i <= 99999; i ++ ) {
		int t = i;
		bool flag = true;
		while (t > 0) {
			if (t % 10 == 4) {
				flag = false;
				break;
			}
			t /= 10;
		}
		if (flag) ans ++ ;
	}
	printf("%d", ans);
    return 0;
}

2.星系炸弹 2017-08-05

#include <cstdio>
int ans;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool valid(int date) {
	int year = date / 10000;
	int month = date % 10000 / 100;
	int day = date % 100;
	if (month == 0 || month > 12) return false;
	if (month != 2 && day > days[month] || day == 0) return false;
	if (month == 2) {
		int leap = year % 100 != 0 && year % 4 == 0 || year % 400 == 0;
		if (day > 28 + leap) return false;
	}
	return true;
}
int main() {
	int d1 = 20150101, d2 = 20141109, c1 = 15, c2 = 1000, cnt = -1;
	for (int i = d2; ; i ++ ) {
		if (valid(i)) {
			cnt ++ ;
		}
		if (cnt == c2) {
			printf("%d-%02d-%02d\n", i / 10000, i % 10000 / 100, i % 100);
			return 0;
		}
	}
    return 0;
}

3.三羊献瑞 1085 g != 1

法一 直接 枚举

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//    祥4 瑞3 生5 辉6
//    三0 羊1 献2 瑞3
//三0 羊1 生5 瑞3 气7 
//     a   b   c   d
//     1   e   f   b
//  1  e   c   b   g
// a * 1000 + b * 100 + c * 10 + d
// 1000 + e * 100 + f * 10 + b
// 10000 + e * 1000 + c * 100 + b * 10 + f
int main() {
	for (int a = 0; a <= 9; a ++ )
		for (int b = 0; b <= 9; b ++ ) {
			for (int c = 0; c <= 9; c ++ ) {
				for (int d = 0; d <= 9; d ++ ) {
					for (int e = 0; e <= 9; e ++ ) {
						for (int f = 0; f <= 9; f ++ ) {
							for (int g = 0; g <= 9; g ++ ) {
								if (g == 1) continue;
								if (a == b || a == c || a == d || a == e || a == f || a == g) continue;
								if (b == c || b == d || b == e || b == f || b == g) continue;
								if (c == d || c == e || c == f || c == g) continue;
								if (d == e || d == f || d == g) continue;
								if (e == f || e == g) continue;
								if (f == g) continue;
								int x = a * 1000 + b * 100 + c * 10 + d,
								y = 1000 + e * 100 + f * 10 + b,
								z = 10000 + e * 1000 + c * 100 + b * 10 + g;
								if (x + y == z) {
									printf("%d %d %d %d\n", 1, e, f, b);
									printf("%d %d %d\n", x, y, z);
									cout << ' ' << a <<  b  << c  << d << endl;
									cout << ' ' << 1 <<  e  << f <<  b << endl;
									cout << 1 << e  << c  << b <<  g << endl;
								}
							}
						}
					}
				}
			}
		}
    return 0;
}

法二 全排列 枚举

/*
 9567
 1085
10652
 9567
 1085
10652
*/
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//  0 1 2 3
//  4 5 6 1
//4 5 2 1 7 // 写错 一定要对应正确位置
int main() {
	vector<int> v;
	for (int i = 0; i <= 9; i ++ ) v.push_back(i);
	do {
		int a = (v[0] + v[4]) * 1000 + (v[1] + v[5]) * 100 + (v[2] + v[6]) * 10 + v[3] + v[1];
		int b = v[4] * 10000 + v[5] * 1000 + v[2] * 100 + v[1] * 10 + v[7];
		if (a == b) {
			/*
			for (int i = 0; i <= 6; i ++ ) cout << v[i];
			cout << endl;
			*/
			if (v[4] != 1) continue;
			cout << ' ' << v[0] << v[1] << v[2] << v[3] << endl;
			cout << ' ' << v[4] << v[5] << v[6] << v[1] << endl;
			cout << v[4] << v[5] << v[2] << v[1] << v[7] << endl;
		}
	} while (next_permutation(v.begin(), v.end()));
    return 0;
}

4.格子中输出

//    printf("%*s%s%*s",_____________________________________________);  //填空
    printf("%*s%s%*s",(width-strlen(buf)-2)/2,"",buf,(width-strlen(buf)-2)/2,"");  //填空
    printf("|\n");

5.九数组分数

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
	vector<int> v;
	/*
	for (int i = 0; i <= 9; i ++ ) v.push_back(i);
	do {
		int a = v[1] * 100 + v[2] * 10 + v[3];
		int b = v[4] * 100 + v[5] * 10 + v[6];
		int c = v[7] * 100 + v[8] * 10 + v[9];
		if (a * 2 == b && a * 3 == c) {
			cout << a << endl;
		}
	} while (next_permutation(v.begin() + 1, v.end()));
	*/
	for (int i = 1; i <= 9; i ++ ) v.push_back(i);
	do {
		int a = v[0] * 100 + v[1] * 10 + v[2];
		int b = v[3] * 100 + v[4] * 10 + v[5];
		int c = v[6] * 100 + v[7] * 10 + v[8];
		if (a * 2 == b && a * 3 == c) {
			cout << a << ' ';
		}
	} while (next_permutation(v.begin(), v.end()));
    return 0;
}

6.加法变乘法 16

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
	int sum = 1225;
	vector<int> vec;
	for (int i = 1; i <= 48; i ++ ) {
		for (int j = i + 2; j <= 48; j ++ ) {
			sum -= i + i + 1;
			sum -= j + j + 1;
			sum += i * (i + 1);
			sum += j * (j + 1);
			if (sum == 2015) {
				vec.push_back(i);
			}
			sum = 1225;
		}
	}
	cout << vec[1] << endl;
    return 0;
}

7.牌型种数 3598180

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

int ans;

void f(int k,int cnt) {
    if(cnt>13||k>13)return;
    if(k==13&&cnt==13){
        ans++;
        return;
    }
    for (int i = 0; i < 5; ++i) {
        f(k+1,cnt+i);
    }
}


int main(int argc, const char *argv[]) {
    f(0, 0);
    cout << ans << endl;
    return 0;
}

8.移动距离

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int main() {
    int w, m, n;
    scanf("%d %d %d", &w, &m, &n);
    m --, n -- ;
    int x1 = m / w, x2 = n / w;
    int y1 = m % w, y2 = n % w;
    if (x1 % 2) y1 = w - 1 - y1;
    if (x2 % 2) y2 = w - 1 - y2;
    printf("%d\n", abs(x1 - x2) + abs(y1 - y2));
    return 0;
}

9.垒骰子_递归

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 6, mod = 1e9 + 7;

int n, m;

int get_op(int x) {
    if (x >= 3) return x - 3;
    else return x + 3;
}

void mul(int c[][N], int a[][N], int b[][N]) // C = A * B
{
    static int t[N][N];
    memset(t, 0, sizeof t);
    for (int i = 0; i < N; i ++ )
        for (int j = 0; j < N; j ++ )
            for (int k = 0; k < N; k ++ )
                t[i][j] = (t[i][j] + (LL)a[i][k] * b[k][j]) % mod;
    memcpy(c, t, sizeof t);
}

int main() {
    scanf("%d %d", &n, &m);
    
    int a[N][N];
    for (int i = 0; i < N; i ++ )
        for (int j = 0; j < N; j ++ )
            a[i][j] = 4;
    
    while (m -- ) {
        int x, y;
        scanf("%d %d", &x, &y);
        x --, y -- ;
        a[x][get_op(y)] = 0;
        a[y][get_op(x)] = 0;
    }
    
    int f[N][N] = {4, 4, 4, 4, 4, 4}; // F[1]
    for (int k = n - 1; k; k >>= 1) { // 快速幂
        if (k & 1) mul(f, f, a); // F = F * A
        mul(a, a, a); // A = A * A
    }
    
    int res = 0;
    for (int i = 0; i < N; i ++ ) res = (res + f[0][i]) % mod;
    printf("%d\n", res);
    
    return 0;
}

10.生命之树

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 100010, M = N * 2;

int n;
int w[N];
int h[N], e[M], ne[M], idx;
LL f[N];

void add(int a, int b)  // 添加一条边a->b
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}


void dfs(int u, int father) {
    f[u] = w[u];
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (j != father) {
            dfs(j, u);
            f[u] += max(0ll, f[j]);
        }
    }
}

int main() {
    scanf("%d", &n);
    memset(h, -1, sizeof h);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]);
    for (int i = 0; i < n - 1; i ++ ) {
        int a, b;
        scanf("%d %d", &a, &b);
        add(a, b), add(b, a);
    }
    dfs(1, -1);
    LL res = f[1];
    for (int i = 2; i <= n; i ++ ) res = max(res, f[i]);
    printf("%lld\n", res);
    return 0;
}

2016蓝桥杯省赛

1.1~100层

每层累加1~层数个数,求整栋楼总和

#include <cstdio>
#include <iostream>
using namespace std;
int main() {
	int n = 100, sum = 0;
	for (int i = 1; i <= n; i ++ ) {
		int t = i, s = 0;
		for (int j = 1; j <= t; j ++ ) s += j;
		sum += s;
	} 
	printf("%d\n", sum);
	return 0;
} 

2.年龄等差数列

x 1-100 x + 1 - 100三层循环26-33

#include <cstdio>
#include <iostream>
using namespace std;
int main() {
	for (int i = 1; i <= 100; i ++ ) {
		for (int j = i + 1; j <= 100; j ++ ) {
			int sum = 0;
			for (int k = i; k <= j; k ++ ) {
				sum += k;
			}
			if (sum == 236) {
				printf("%d %d", i, j);
			}
		}
	}
	return 0;
} 

3.全排列next_permutation

精度double

从1开始next_permutation(a + 1, a + n) n 为总个数 + 1

sort(a, a + n) 从0开始

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[10];
int sum = 0;
int main() {
	for (int i = 1; i <= 9; i ++ ) a[i] = i;
	do {
		int m = a[4] * 100 + a[5] * 10 + a[6];
		int n = a[7] * 100 + a[8] * 10 + a[9];
		if (a[1] + (double)a[2] / a[3] + (double)m / n == 10) sum ++ ;
	} while (next_permutation(a + 1, a + 10));
	printf("%d\n", sum);
	return 0;
} 

4. quick_sort(q, l, j), quick_sort(q, j + 1, r)

answer : swap(a, p, j)

void quick_sort(int q[], int l, int r) {
	if (l >= r) return;
	int i = l - 1, j = r + 1, x = q[i + j >> 1];
	while (i < j) {
	    do i ++ ; while (q[i] < x);
	    do j -- ; while (q[j] > x);
	    if (i < j) swap(q[i], q[j]);
	}
	quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

5.抽签 answer : f(a, k + 1, m - i, b);

6.填数 相邻数不是连续数 ans = 1580

#include <iostream>
#include <stdlib.h>

using namespace std;

int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int ans;

bool check(){
         if(abs(a[0]-a[1])==1||
            abs(a[0]-a[3])==1||
            abs(a[0]-a[4])==1||
            abs(a[0]-a[5])==1||

            abs(a[1]-a[2])==1||
            abs(a[1]-a[4])==1||
            abs(a[1]-a[5])==1||
            abs(a[1]-a[6])==1||

            abs(a[2]-a[5])==1||
            abs(a[2]-a[6])==1||

            abs(a[3]-a[4])==1||
            abs(a[3]-a[7])==1||
            abs(a[3]-a[8])==1||

            abs(a[4]-a[5])==1||
            abs(a[4]-a[7])==1||
            abs(a[4]-a[8])==1||
            abs(a[4]-a[9])==1||

            abs(a[5]-a[6])==1||
            abs(a[5]-a[8])==1||
            abs(a[5]-a[9])==1||

            abs(a[6]-a[9])==1||

            abs(a[7]-a[8])==1||

            abs(a[8]-a[9])==1)
             return false;
    return true;
}

/*考虑第k个位置,一般从0开始*/
void f(int k) {
//出口
    if (k == 10) {
        bool b = check();
        if(b)
            ans++;
        return;
    }


    for (int i = k; i < 10; ++i) {
        //尝试将位置i与位置k交换,以此确定k位的值
        {
            int t = a[i];
            a[i] = a[k];
            a[k] = t;
        }
        f(k + 1);
//        回溯
        {
            int t = a[i];
            a[i] = a[k];
            a[k] = t;
        }

    }
}

int main(int argc, const char *argv[]) {
    f(0);
    cout << ans << endl;
    return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;

int a[5][6];
int vis[10];
int ans;

bool check(int i,int j) {
    for (int x = i - 1; x <= i + 1; ++x) {
        for (int y = j - 1; y <= j + 1; ++y) {
            if (abs(a[x][y] - a[i][j]) == 1)
                return false;
        }
    }
    return true;
}

void f(int x, int y) {
    if (x == 3 && y == 4) {
        ans++;
        return;
    }
//    从0~9中抓一个
    for (int i = 0; i < 10; ++i) {
        if (vis[i] == 0) {//i没有被用过
            a[x][y] = i;//填数
            if(!check(x,y)){//不合法,恢复并continue
                a[x][y]=-10;
                continue;
            }
            vis[i] = 1;//标记为已访问
            if (y == 4)
                f(x + 1, 1);//换行
            else
                f(x, y + 1);//继续填右侧的格子
            {vis[i] = 0;//回溯
            a[x][y]=-10;}

        }
    }

}

void init() {
    for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 6; ++j) {
            a[i][j] = -10;
        }
    }
}

int main(int argc, const char *argv[]) {
    init();
    f(1, 2);
    cout << ans << endl;
    return 0;
}

7.剪邮票 116

#include <algorithm>
#include <iostream>

using namespace std;

int a[] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};//它的每个排列代表着12选5的一个方案
int ans;

void dfs(int g[3][4], int i, int j) {
    g[i][j] = 0;
    if (i - 1 >= 0 && g[i - 1][j] == 1)dfs(g, i - 1, j);
    if (i + 1 <= 2 && g[i + 1][j] == 1)dfs(g, i + 1, j);
    if (j - 1 >= 0 && g[i][j - 1] == 1)dfs(g, i, j - 1);
    if (j + 1 <= 3 && g[i][j + 1] == 1)dfs(g, i, j + 1);
}

bool check(int path[12]) {
    int g[3][4];
//    将某个排列映射到二维矩阵上
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (path[i * 4 + j] == 1) g[i][j] = 1;
            else g[i][j] = 0;
        }
    }
    int cnt = 0;//连通块的数目
//    g上面就有5个格子被标记为1,现在才用dfs做连通性检查,要求只有一个连通块
    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (g[i][j] == 1) {
                dfs(g, i, j);
                cnt++;
            }
        }
    }
    return cnt == 1;
}

bool vis[12];

void f(int k, int path[12]) {
    if (k == 12) {
        if (check(path)) {
            ans++;
        }
    }
    for (int i = 0; i < 12; ++i) {
        if (i>0&&a[i]==a[i-1]&&!vis[i-1])continue;//现在准备选取的元素和上一个元素相同,但是上一个元素还没被使用

        if(!vis[i]){//没有被用过的元素可以抓入到path
            vis[i]=true;//标记为已访问
            path[k]=a[i];//将a[i]填入到path[k]中
            f(k + 1, path);//递归
            vis[i]=false;//回溯
        }

    }
}

int main(int argc, const char *argv[]) {
    int path[12];
    f(0, path);
    printf("%d", ans);
    return 0;
}

8.四平方和 枚举 二分

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 2500010;
struct Sum {
	int s, c, d;
	bool operator< (const Sum &t)const {
		if (s != t.s) return s < t.s;
		if (c != t.c) return c < t.c;
		return d < t.d;
	}
}sum[N]; 
int n, m;
int main() {
	scanf("%d", &n);
	for (int c = 0; c * c <= n; c ++ ) {
		for (int d = c; c * c + d * d <= n; d ++ ) {
			sum[m ++ ] = {c * c + d * d, c, d};
		}
	}
	sort(sum, sum + m);
	for (int a = 0; a * a <= n; a ++ ) {
		for (int b = 0; a * a + b * b <= n; b ++ ) {
			int t = n - a * a - b * b;
			int l = 0, r = m - 1;
			while (l < r) {
				int mid = l + r >> 1;
				if (sum[mid].s >= t) r = mid;
				else l = mid + 1;
			}
			if (sum[l].s == t) {
				printf("%d %d %d %d\n", a, b, sum[l].c, sum[l].d);
				return 0;
			}
		}
	}
	return 0;
}

9.交换瓶子 并查集 变形

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10010;
int b[N];
bool st[N];
int n;
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]);
	int cnt = 0;
	for (int i = 1; i <= n; i ++ ) {
		if (!st[i]) {
			cnt ++ ;
			for (int j = i; !st[j]; j = b[j]) {
				st[j] = true;
			}
		}
	} 
	printf("%d\n", n - cnt);
	return 0;
}

10.最大比例 数论

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 110;
typedef long long LL;
int n;
LL a[N], b[N], x[N];
LL gcd(LL a, LL b) {
	return b ? gcd(b, a % b) : a;
}
LL gcd_sub(LL a, LL b) {
	if (a < b) swap(a, b);
	if (b == 1) return a;
	return gcd_sub(b, a / b);
}
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i ++ ) scanf("%lld", &x[i]);
	sort(x, x + n);
	int cnt = 0;
	for (int i = 1; i < n; i ++ )
		if (x[i] != x[i - 1]) {
			LL d = gcd(x[i], x[0]);
			a[cnt] = x[i] / d;
			b[cnt] = x[0] / d;
			cnt ++ ;
		}
	LL up = a[0], down = b[0];
	for (int i = 1; i < cnt; i ++ ) {
		up = gcd_sub(up, a[i]);
		down = gcd_sub(down, b[i]);
	}
	printf("%lld/%lld\n", up, down);
	return 0;
}

2017蓝桥杯省赛

1.购物单 5200元

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
	double s = 
      180.90 *      88
+      10.25 *      65
+      56.14 *       90
+     104.65 *       90
+     100.30 *      88
+     297.15 *       50
+      26.75 *      65
+     130.62 *       50
+     240.28 *      58 
+     270.62 *       80 
+     115.87 *      88 
+     247.34 *      95 
+      73.21 *       90 
+     101.00 *       50
+      79.54 *       50
+     278.44 *       70 
+     199.26 *       50
+      12.97 *       90 
+     166.30 *      78 
+     125.50 *      58 
+      84.98 *       90 
+     113.35 *      68 
+     166.57 *       50
+      42.56 *       90 
+      81.90 *      95 
+     131.78 *       80 
+     255.89 *      78 
+     109.17 *       90 
+     146.69 *      68 
+     139.33 *      65 
+     141.16 *      78 
+     154.74 *       80 
+      59.42 *       80 
+      85.44 *      68 
+     293.70 *      88 
+     261.79 *      65 
+      11.30 *      88 
+     268.27 *      58 
+     128.29 *      88 
+     251.03 *       80 
+     208.39 *      75 
+     128.88 *      75 
+      62.06 *       90 
+     225.87 *      75 
+      12.89 *      75 
+      34.28 *      75 
+      62.16 *      58 
+     129.12 *       50
+     218.37 *       50
+     289.69 *       80;
	s /= 100;
	printf("%lf", s); 
	return 0;
}

2.等差素数列 210

#include <algorithm>
#include <iostream>
#include <set>
using namespace std;
typedef long long LL;
set<int>all;

bool isPrime(LL t) {
    for (int i = 2; i < t / 2; ++i) {
        if (t % i == 0)return false;
    }
    return true;
}

int f(LL a[], int n) {
    for (int i = 0; i < n; ++i) {//枚举首项
        LL first = a[i];
        for (int delta = 1; delta < a[n - 1] - first; ++delta) {//枚举公差
            int m = first;
            for (int j = 1; j < 10; ++j) {//枚举个数
                m += delta;
                if (all.find(m) == all.end()) //m不是素数
                    break;
                if (m > a[n - 1])break;
                if (j == 9)//已经找到10项
                    return delta;
            }
        }
    }
    return -1;
}
const int N=5000;
LL a[N];
int main(int argc, const char *argv[]) {
    a[0] = 2;
    a[1] = 3;
    all.insert(2);
    all.insert(3);

    int index = 2;
    LL t = 5;
    while (index < N) {
        if (isPrime(t)) {
            a[index++] = t;
            all.insert(t);
        }
        t++;
    }
    cout<<f(a, N)<<endl;
    return 0;
}

3.承压计算 72665192664

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;

LL arr[30][30];
int main(int argc, const char * argv[]) {
    LL factor=1;
    for (int i = 0; i < 30; ++i) {
        factor<<=1;
    }
//    cout <<factor<<endl;
//    输入数据放入二维数组
    for (int i = 0; i < 29; ++i) {
        for (int j = 0; j <= i; ++j) {
            LL a=0;
            scanf("%lld",&a);
            arr[i][j]=a*factor;
        }
    }

//自上而下处理a[i][j]*factor(2的30次方)-->除以2,计入a[i+1][j]和a[i+1][j+1]
//循环处理第1~N-1行
    for (int i = 0; i < 29; ++i) {
        for (int j = 0; j <=i ; ++j) {
            LL ha =arr[i][j]/2;
            arr[i+1][j]+=ha;
            arr[i+1][j+1]+=ha;
        }
    }
//对a[N-1]这一行进行排序,查看最小值与factor之间的倍数关系,决定最大值是多少
    sort(arr[29],arr[29]+30);
    cout<<arr[29][0]/2<<","<<arr[29][29]/2<<endl;
    return 0;
}

4.方格分割 509

#include <iostream>

using namespace std;
int ans;
int dire[][2] = {{-1, 0},
                 {1,  0},
                 {0,  -1},
                 {0,  1}};
int vis[7][7];


void dfs(int x, int y) {
    if (x == 0 || y == 0 || x == 6 || y == 6) {
        ans++;
        return;
    }
//    当前的点标注为已访问
    vis[x][y] = 1;
//    对称点也标注为已访问
    vis[6 - x][6 - y] = 1;
    for (int k = 0; k < 4; ++k) {
        int nx = x + dire[k][0];
        int ny = y + dire[k][1];
//            新坐标
        if (nx < 0 || nx > 6 || ny < 0 || ny > 6)continue;
        if (!vis[nx][ny]) {
            dfs(nx, ny);
        }

    }
    vis[x][y] = 0;
    vis[6 - x][6 - y] = 0;//对称

}

int main(int argc, const char *argv[]) {
    dfs(3, 3);
    cout << ans / 4 << endl;
    return 0;
}

5.取数位

// 不是求最末一位,去掉最末一位进行递归
return f(x/10,k); //填空

6.最大公共子串

a[i][j] = a[i-1][j-1]+1;  //填空

7.日期问题 valid y m d; m d y; d, m, y

#include <iostream>
#include <cstdio>
using namespace std;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool valid(int date) {
	int year = date / 10000;
	int month = date % 10000 / 100;
	int day = date % 100;
	if (month == 0 || month > 12) return false;
	if (day == 0 || month != 2 && day > days[month]) return false;
	if (month == 2) {
		int leap = year % 100 != 0 && year % 4 == 0 || year % 400 == 0;
		if (day > 28 + leap) return false;
	}
	return true;
}
int a, b, c;
int main() {
    scanf("%d/%d/%d", &a, &b, &c);
    for (int i = 19600101; i <= 20591231; i ++ ) {
        if (valid(i)) {
            int y = i / 10000, m = i % 10000 / 100, d = i % 100;
            if (y % 100 == a && m == b && d == c ||
               m == a && d == b && y % 100 == c ||
               d == a && m == b && y % 100 == c) {
                printf("%d-%02d-%02d\n", y, m, d);
            }
        }
    }
    return 0;
}

8.包子凑数 dp

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
int a[110];
bool f[110][N];
int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}
int main() {
	int n;
	scanf("%d", &n);
	int d = 0;
	for (int i = 1; i <= n; i ++ ) {
		scanf("%d", &a[i]);
		d = gcd(d, a[i]);
	}
	if (d != 1) puts("INF");
	else {
		f[0][0] = true;
		for (int i = 1; i <= n; i ++ )
			for (int j = 0; j < N; j ++ ) {
				f[i][j] = f[i - 1][j];
				if (j >= a[i]) f[i][j] |= f[i][j - a[i]];
			}
		int res = 0;
		for (int i = 0; i < N; i ++ )
			if (!f[n][i])
				res ++ ;
		printf("%d\n", res);
	}
	return 0;
}

9.分巧克力

#include <cstdio>
const int N = 100010;
int h[N], w[N];
int n, k;
bool check(int mid) {
	int res = 0;
	for (int i = 0; i < n; i ++ ) {
		res += (h[i] / mid) * (w[i] / mid);
		if (res >= k) return true;
	}
	return false;
}
int main() {
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; i ++ ) scanf("%d %d", &h[i], &w[i]);
	int l = 1, r = 1e5;
	while (l < r) {
		int mid = l + r + 1 >> 1;
		if (check(mid)) l = mid;
		else r = mid - 1;
	}
	printf("%d\n", r);
	return 0;
}

10. k倍区间

#include <cstdio>
typedef long long LL;
const int N = 100010;
int n, k;
LL s[N], cnt[N];
int main() {
	scanf("%d %d", &n, &k);
	for (int i = 1; i <= n; i ++ ) {
		scanf("%lld", &s[i]);
		s[i] += s[i - 1];
	}
	LL res = 0;
	cnt[0] = 1;
	for (int i = 1; i <= n; i ++ ) {
		res += cnt[s[i] % k];
		cnt[s[i] % k] ++ ;
	}
	printf("%lld\n", res);
	return 0;
}

2018蓝桥杯省赛

1.20000504该年第几天 31 29 31 30 4 125天

2.明码 9 ^ 9

#include <stdio.h>
#include <stdlib.h>

void print_bin(int n)
{
    int l = sizeof(n)*8;//总位数。
    int i;
    if(i == 0)
    {
         printf("00000000");
         return;
     }
     for(i = l-1; i >= 8; i --)//略去高位0,1.
    {
        if(n&(1<<i)==0||n&(1<<i)==1) break;
}
    for(;i>=0; i --)
        printf("%d", (n&(1<<i)) != 0);
}
int main(int argc, char *argv[])
{
  int a,b=0;
  while(scanf("%d",&a)==1){
    print_bin(a); 
      b++;
      if(b%2==0)
   printf("\n");
  }
  return 0;
}
#include <cstdio>
typedef long long LL;
int main() {
	LL res = 1;
	for (int i = 1; i <= 9; i ++ ) {
		res *= 9;
	}
	printf("%lld\n", res);
	return 0;
}

3.乘积尾零 % 2,5 == 0 是2,5的倍数

#include <cstdio>
#include <algorithm>
using namespace std; 
int two, five;
int main() {
	/*
	for (int i = 1; i <= 10; i ++ ) {
		for (int j = 1; j <= 10; j ++ ) {
			int x;
			scanf("%d", &x);
			while (x % 2 == 0) x /= 2, two ++ ;
			while (x % 5 == 0) x /= 5, five ++ ; 
		} 
	}
	printf("%d\n", min(two, five));
	*/
	printf("%d", 31);
	return 0;
}

4.测试次数 dp

#include <cstdio>
#include <algorithm>
using namespace std; 
int dp[4][1005];
int main() {
	for (int i =0; i <= 1000; i ++ ) {
		dp[1][i] = i;
	}
	for (int cnt = 2; cnt <= 3; cnt ++ ) {
		for (int ind = 1; ind <= 1000; ind ++ ) {
			int val = 10000, m;
			for (int k = 1; k <= ind; k ++ ) {
				m = max(dp[cnt - 1][k - 1], dp[cnt][ind - k]) + 1;
				if (val > m) val = m;
			}
			dp[cnt][ind] = val;
		}
	}
	printf("%d\n", dp[3][1000]);
	return 0;
}

5.快速排序

#include <stdio.h>
#include <algorithm>
using namespace std; 

int quick_select(int a[], int l, int r, int k) {
	int p = rand() % (r - l + 1) + l;
	int x = a[p];
	{int t = a[p]; a[p] = a[r]; a[r] = t;}
	int i = l, j = r;
	while(i < j) {
		while(i < j && a[i] < x) i++;
		if(i < j) {
			a[j] = a[i];
			j--;
		}
		while(i < j && a[j] > x) j--;
		if(i < j) {
			a[i] = a[j];
			i++;
		}
	}
	a[i] = x;
	p = i;
	if(i - l + 1 == k) return a[i];
	if(i - l + 1 < k) return quick_select(a, i, r, k); //填空
	else return quick_select(a, l, i - 1, k);
}
	
int main()
{
	int a[] = {1, 4, 2, 8, 5, 7, 23, 58, 16, 27, 55, 13, 26, 24, 12};
	printf("%d\n", quick_select(a, 0, 14, 5));
	return 0;
}

6.递增三元组 预处理前缀和

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 100010;

int n;
int a[N], b[N], c[N];
int as[N];
int cs[N];
int cnt[N], s[N];

int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]), a[i] ++ ;
	for (int i = 0; i < n; i ++ ) scanf("%d", &b[i]), b[i] ++ ;
	for (int i = 0; i < n; i ++ ) scanf("%d", &c[i]), c[i] ++ ;
	// 求as[]
	for (int i = 0; i < n; i ++ ) cnt[a[i]] ++ ;
	for (int i = 1; i < N; i ++ ) s[i] = s[i - 1] + cnt[i];
	for (int i = 0; i < n; i ++ ) as[i] = s[b[i] - 1];
	// 求cs[]
	memset(cnt, 0, sizeof cnt);
	memset(s, 0, sizeof s);
	for (int i = 0; i < n; i ++ ) cnt[c[i]] ++ ;
	for (int i = 1; i < N; i ++ ) s[i] = s[i - 1] + cnt[i];
	for (int i = 0; i < n; i ++ ) cs[i] = s[N - 1] - s[b[i]];
	// 枚举每个b[i]
	LL res = 0;
	for (int i = 0; i < n; i ++ ) res += (LL)as[i] * cs[i];
	printf("%d\n", res);
	return 0; 
}

7.螺旋折线 规律 计数

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

using namespace std;

typedef long long LL;
int main() {
	int x, y;
	scanf("%d %d", &x, &y);
	
	if (abs(x) <= y) { // 上方 
		int n = y;
		printf("%lld\n", (LL)(2 * n - 1) * (2 * n) + x - (-n));
	} else if (abs(y) <= x) { // 右方 
		int n = x;
		printf("%lld\n", (LL)(2 * n) * (2 * n) + n - y);
	} else if (abs(x) <= abs(y) + 1 && y < 0) { // 下方 
		int n = abs(y);
		printf("%lld\n", (LL)(2 * n) * (2 * n + 1) + n - x);
	} else { // 左方 
		int n = abs(x);
		printf("%lld\n", (LL)(2 * n - 1) * (2 * n - 1) + y - (-n + 1));
	}
	return 0;
}

8.日志统计 bfs

#include <cstdio>
#include <iostream>
#include <algorithm>
#define x first
#define y second

using namespace std;

const int N = 1e5 + 10;

typedef pair<int, int> PII;

int n, d, k;
PII logs[N];
int cnt[N];
bool st[N];

int main() {
	scanf("%d %d %d", &n, &d, &k); // n组 区间d k个赞 
	for (int i = 0; i < n; i ++ ) {
		scanf("%d %d", &logs[i].x, &logs[i].y); // 时间 序号 
	}
	sort(logs, logs + n);
	for (int i = 0, j = 0; i < n; i ++ ) {
		int id = logs[i].y;
		cnt[id] ++ ;
		while (logs[i].x - logs[j].x >= d) { // 区间 大于 限制时间 
			cnt[logs[j].y] -- ; // 记录少一个 
			j ++ ; // j ++ 并且向前走一位 
		}
		if (cnt[id] >= k) st[id] = true;
	}
	for (int i = 0; i <= 100000; i ++ ) {
		if (st[i])
			printf("%d\n", i);
	}
	return 0;
}

9.全球变暖 bfs

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;

int n;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

void bfs(int sx, int sy, int &total, int &bound) {
	int hh = 0, tt = 0;
	q[0] = {sx, sy};
	st[sx][sy] = true;
	
	while (hh <= tt) {
		PII t = q[hh ++ ];
		
		total ++ ;
		bool is_bound = false;
		for (int i = 0; i < 4; i ++ ) {
			int x = t.x + dx[i], y = t.y + dy[i];
			if (x < 0 || x >= n || y < 0 || y >= n) continue;
			if (st[x][y]) continue;
			if (g[x][y] == '.') {
				is_bound = true;
				continue;
			}
			
			q[ ++ tt] = {x, y};
			st[x][y] = true;
		}
		
		if (is_bound) bound ++ ;
	}
}

int main() {
	scanf("%d", &n);
	
	for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
	
	int cnt = 0;
	for (int i = 0; i < n; i ++ )
		for (int j = 0; j < n; j ++ )
			if (!st[i][j] && g[i][j] == '#') {
				int total = 0, bound = 0;
				bfs(i, j, total, bound);
				if (total == bound) cnt ++ ;
			} 
	printf("%d\n", cnt);
	return 0;
}

10.乘积最大 贪心

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 100010, mod = 1e9 + 9;

int n, k;
int a[N];

int main() {
	scanf("%d %d", &n, &k);
	for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
	sort(a, a + n);
	
	int res = 1;
	int l = 0, r = n - 1;
	int sign = 1;
	if (k % 2) {
		res = a[r -- ];
		k -- ;
		if (res < 0) sign = -1;
	}
	while (k) {
		LL x = (LL)a[l] * a[l + 1], y = (LL)a[r - 1] * a[r];
		if (x * sign > y * sign) {
			res = x % mod * res % mod;
			l += 2;
		} else {
			res = y % mod * res % mod;
			r -= 2;
		}
		k -= 2;
	}
	printf("%d\n", res);
	
	return 0;
}
举报

相关推荐

0 条评论