目录
第五题:抽签(dfs)
第七题:剪邮票(连通块+dfs)
题目来源:
第一题:煤球数目(简单数学找规律)
分析:
(1)1=1
(2)3=1+2
(3)6=1+2+3
(4)10=1+2+3+4
需要注意的是,题目所求的是100层及以上煤球的总数量
#include<iostream>
using namespace std;
int main()
{
long long sum = 0;
int i = 0;
for (int i = 1; i <= 100; i++)
{
for (int j = 1; j <= i; j++)
{
sum += j;
}
}
cout << sum << endl;//171700
return 0;
}
第二题:生日蜡烛(暴力枚举+数学)
核心思路:
外层for循环枚举,从什么时候开始过生日,内层for+1枚举,直到总和==236,跳出循环,输出外层for循环枚举的变量值即可
#include<iostream>
using namespace std;
int main()
{
for (int i = 1; i <= 100; i++)
{
long long sum = 0;//注意细节即可
for (int j = i; j <= 100; j++)
{
sum += j;
if (sum == 236)
{
cout << i << endl;
return 0;
}
}
}
return 0;
}
第三题:凑算式(排列组合+暴力枚举)
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
int num[9] = { 1,2,3,4,5,6,7,8,9 };
int cnt = 0;
do
{
float a = num[0];
float b = num[1] * 1.0 / num[2];
float c = (num[3] * 100.0 + num[4] * 10 + num[5]) / (num[6] * 100 + num[7] * 10 + num[8]);
if (fabs(a + b + c - 10) <= 1e-5)//浮点数判断等于的方法:小于一个很小的即可
{
cnt++;
}
} while (next_permutation(num, num + 9));
cout << cnt << endl;
return 0;
}
第四题:快速排序(送分)
#include <stdio.h>
void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int partition(int a[], int p, int r)
{
int i = p;
int j = r + 1;
int x = a[p];
while(1)
{
while(i<r && a[++i]<x);
while(a[--j]>x);
if(i>=j) break;
swap(a,i,j);
}
______________________;//填空
return j;
}
void quicksort(int a[], int p, int r)
{
if(p<r)
{
int q = partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}
int main()
{
int i;
int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
int N = 12;
quicksort(a, 0, N-1);
for(i=0; i<N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
答案为:swap(a,p,j);
第五题:抽签
#include<iostream>
#include<cstdio>
using namespace std;
#define N 6
#define M 5
#define BUF 1024
void f(int a[], int k, int m, char b[])
{
int i,j;
if(k==N)
{
b[M] = 0;
if(m==0) printf("%s\n",b);
return;
}
for(i=0; i<=a[k]; i++)
{
for(j=0; j<i; j++)
b[M-m+j] = k+'A';
f(a,k+1,m-i,b);; //填空位置
}
}
int main()
{
int a[N] = {4,2,2,1,1,3};
char b[BUF];
f(a,0,M,b);
return 0;
}
解释看到return,以及题意,顿时就会联想到dfs,那么就可以知道了,第一个参数必然是数组a,最后一个参数必然是数组b,这些都没得跑了
那么看到第一层的for循环,就可以知道,它在枚举参赛队伍的编号,所以k就是代表队伍编号的意思,与数组下标同理,那么枚举完这个队伍,肯定要向下一层枚举,所以k+1
看到main函数里:第一开始枚举的时候第三个参数传的是 M :5 ,回看题目,可以知道这是一支五人的队伍,那么随着枚举次数的增加,所以m的真实含义是剩余的人数含义,
f(a, k+1, m-i, b); //填空位置
第六题:方格填数(究极暴力+排列)
题解来自:
#include<iostream>
#include<algorithm>
using namespace std;
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int main()
{
int ans = 0;
do
{
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) ans ++;
}while(next_permutation(a, a + 10));
cout << ans << endl;
return 0;
}
第七题:剪邮票
#include<iostream>
using namespace std;
const int N = 15;
int ans;
int p[N];
int e[N][N];
bool used[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void dfs(int u, int start)
{
if (u == 5)
{
for (int i = 1; i <= 12; i++) p[i] = i;
for (int i = 1; i <= 12; i++)
{
for (int j = 1; j <= 12; j++)
{
if (e[i][j] && used[i] && used[j])
{
p[find(i)] = find(j);
}
}
}
int cnt = 0;
for (int i = 1; i <= 12; i++)
{
if (used[i] && p[i] == i)
{
cnt++;
}
}
if (cnt == 1) ans++;
return;
}
for (int i = start; i <= 12; i++)
{
if (!used[i])
{
used[i] = true;
dfs(u + 1, i + 1);
used[i] = false;
}
}
}
int main()
{
e[1][2] = e[1][5] = 1;
e[2][1] = e[2][3] = e[2][6] = 1;
e[3][2] = e[3][4] = e[3][7] = 1;
e[4][3] = e[4][8] = 1;
e[5][1] = e[5][6] = e[5][9] = 1;
e[6][2] = e[6][5] = e[6][7] = e[6][10] = 1;
e[7][3] = e[7][6] = e[7][8] = e[7][11] = 1;
e[8][4] = e[8][7] = e[8][12] = 1;
e[9][5] = e[9][10] = 1;
e[10][6] = e[10][9] = e[10][11] = 1;
e[11][7] = e[11][10] = e[11][12] = 1;
e[12][8] = e[12][11] = 1;
dfs(0, 1);
cout << ans << endl;
return 0;
}
第八题:四平方和(数学+二分)
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
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()
{
cin >> 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;
}
第九题:交换瓶子(数学)
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 10010;
int n;
int b[N];
bool st[N];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> 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;
}
第十题:最大比例(等比数列+数论)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 110;
int n;
LL x[N];//存放输入的数字
LL a[N], b[N];//分别表示分子和分母
LL gcd(LL a, LL b)//辗转相除
{
return b ? gcd(b, a % b) : a;
}
LL gcd_sub(LL a, LL b)//更相减损
{
if (b > a)swap(a, b);
if (b == 1)return a;
return gcd_sub(b, a / b);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)cin >> x[i];//读入
sort(x, x + n);//排序,方便找到首项
LL dd = 0;
int cnt = 0;
for (int i = 1; i < n; i++)
{
if (x[i] != x[i - 1])//去重:重复的不计入考虑范围
{
dd = gcd(x[i], x[0]);//最大公约数
a[cnt] = x[i] / dd;//a[1]=x[i]/dd
b[cnt] = x[0] / dd;
cnt++;
}
}
LL up = a[0], down = b[0];//up分子 down分母
for (int i = 1; i < cnt; i++)//分开求分子分母的指数最大公约数
{
up = gcd_sub(up, a[i]);
down = gcd_sub(down, b[i]);
}
cout << up << "/" << down;
return 0;
}