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;
}