目录
1.车的位置(搜索)
问题描述
在一个n*n的棋盘中,每个格子中至多放置一个车,且要保证任何两个车都不能相互攻击,有多少中放法(车与车之间是没有差别的)
输入格式
包含一个正整数n
输出格式
一个整数,表示放置车的方法数
样例输入
2
样例输出
7
数据规模和约定
n<=8
【样例解释】一个车都不放为1种,放置一个车有4种,放置2个车有2种。
示例代码
#include<iostream>
#include<algorithm>
using namespace std;
int n, sum = 0, f[9] = { 0 };
int ans = 0;
void dfs(int sum) {
if (sum == n) {//如果所有行都已经遍历完
ans++;
}
else {
for (int i = 0; i <= n; i++) {
if (i == 0) {//如果sum+1行不放置车
sum++;
dfs(sum);
sum--;
}
else {//如果当前行放置车
if (f[i] == 0) {//如果当前列没有放置过车
f[i] = 1;
sum++;
dfs(sum);
sum--;
f[i] = 0;
}
}
}
}
}
int main() {
cin >> n;
dfs(sum);
cout << ans;
return 0;
}
2.24点(搜索)
问题描述
24点游戏是一个非常有意思的游戏,很流行,玩法很简单:给你4张牌,每张牌上有数字(其中A代表1,J代表11,Q代表12,K代表13),你可以利用数学中的加、减、乘、除以及括号想办法得到24,例如:
((A*K)-J)*Q等价于((1*13)-11)*12=24
加减乘不用多说了,但除法必须满足能整除才能除!这样有一些是得不到24点的,所以这里只要求求出不超过24的最大值。
输入格式
输入第一行N(1<=N<=5)表示有N组测试数据。每组测试数据输入4行,每行一个整数(1到13)表示牌值。
输出格式
每组测试数据输出一个整数,表示所能得到的最大的不超过24的值。
样例输入
3
3
3
3
3
1
1
1
1
12
5
13
1
样例输出
24
4
21
示例代码
#include<iostream>
#include<algorithm>
using namespace std;
int n, a[5][5], ans = 0, b[4], temp1, temp2, temp3;
int sum = 0;
int xuanze(int i, int c, int d) {//判断是哪种运算符
int hhh = 1;
switch (i) {
case 0:hhh = c + d; break;//加法
case 1:hhh = c - d; break;//减法
case 2:hhh = c * d; break;//乘法
case 3:hhh = c % d; break;//求余
}
return hhh;
}
void dfs(int index, int sum) {//针对先a后b再c最后d的运算顺序
if (sum == 3) {//如果运算符已经分配完毕
if (b[sum] <= 24) {//如果结果小于24则符合题目
ans = max(ans, b[sum]);
}
}
else {
for (int i = 0; i <= 3; i++) {//选一种运算符运算
b[sum + 1] = xuanze(i, b[sum], a[index][sum + 1]);
if (b[sum + 1] != 0 && i == 3) {//如果选择的是除法而且不能够整除,即运算不规范
return;//返回上一步,还有一个原因是因为这个for循环已经结束了
}
else {
if (i == 3) {
b[sum + 1] = b[sum] / a[index][sum + 1];//可以整除,求商
}
sum++;
dfs(index, sum);
sum--;
}
}
}
}
void twoo(int index) {//针对两堆数据,(a+b)*(c+d)这种
for (int i = 0; i <= 3; i++) {//a和b之间的运算符选择
if (i == 3) {
if (a[index][1] == 0) {//a和b之间能否除法
break;
}
}
temp1 = xuanze(i, a[index][0], a[index][1]);
if (i == 3) {
if (temp1 == 0) {//如果能整除
temp1 = a[index][0] / a[index][1];
}
else {//如果不能整除
break;
}
}
for (int j = 0; j <= 3; j++) {//c和d之间的运算符选择
if (j == 3) {
if (a[index][3] == 0) {//c和d之间能否除法
break;
}
}
temp2 = xuanze(j, a[index][2], a[index][3]);
if (j == 3) {
if (temp2 == 0) {//如果可以整除
temp2 = a[index][2] / a[index][3];
}
else {//如果不能整除
break;
}
}
for (int k = 0; k <= 3; k++) {//(ab)与(cd)之间的运算符选择
if (k == 3 && temp2 == 0) {//如果不能使用除法
break;
}
temp3 = xuanze(k, temp1, temp2);
if (k == 3) {
if (temp3 == 0) {//可以整除
temp3 = temp1 / temp2;
}
else {//不可以整除
break;
}
}
if (temp3 <= 24) {//符合条件的找最大值
ans = max(temp3, ans);
}
}
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 4; j++) {
cin >> a[i][j];
}
sort(a[i], a[i] + 4);//从小到大排序,为next_permutation函数铺垫
}
for (int i = 0; i < n; i++) {
ans = 0;
do {
sum = 0;
b[0] = a[i][0];
dfs(i, sum);
sum = 0;
twoo(i);
} while (next_permutation(a[i], a[i] + 4) != 0);//只要数组a中的元素还能排序就继续运行
cout << ans << endl;
}
return 0;
}
3.最大分解(贪心)
问题描述
给出一个正整数n,求一个和最大的序列a0,a1,a2,……,ap,满足n=a0>a1>a2>……>ap且ai+1是ai的约数,输出a1+a2+……+ap的最大值
输入格式
输入仅一行,包含一个正整数n
输出格式
一个正整数,表示最大的序列和,即a1+a2+……+ap的最大值
样例输入
10
样例输出
6
数据规模和约定
1<n<=10^6
样例说明
p=2
a0=10,a1=5,a2=1,6=5+1
示例代码
#include<iostream>
#include<algorithm>
using namespace std;
int ans = 0, n, temp;
int qiuyue(int a) {//找到除了本身的最大约数
for (int i = a / 2; i >= 1; i--) {
if (a % i == 0) {
return i;
}
}
}
int main() {
cin >> n;
if (n == 1) {//如果输入的是1,只能为1
cout << 1;
return 0;
}
temp = n;
do {
temp = qiuyue(temp);//最大约数进入下一次循环
ans += temp;
} while (temp != 1);//temp=1代表循环结束,没法继续分解
cout << ans;
}
4.RP大冒险
问题描述
请尽情使用各种各样的函数来测试你的RP吧~~~
输入格式
一个数N表示测点编号。
输出格式
一个0~9的数。
样例输入
0
样例输出
X
{当且仅当输出仅有一个数X且X为0~9的数时你的得分不为零,此时你的得分为系统根据你的输出而计算出的你本次的RP。}
数据规模和约定
测点编号为1~10,且stdans随机。
究竟使用怎样的函数才能获得较高的RP呢?指数函数?幂函数?斐波那契数?圆周曲线的导数函数?好想尝试一下哦~
示例代码
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int main() {
cin >> n;
n = n % 9;
n = 9 - n;
cout << n;
}
只要保证输出在0-9,想怎么写怎么写
5.士兵杀敌(二)
问题描述
南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的。
小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧。
南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新增的杀敌数。
输入格式
多组测试数据,以EOF结尾;
每组第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示指令的条数。(1<M<100000)
随后的一行是N个整数,ai表示第i号士兵杀敌数目。(0<=ai<=100)
随后的M行每行是一条指令,这条指令包含了一个字符串和两个整数,首先是一个字符串,如果是字符串QUERY则表示南将军进行了查询操
作,后面的两个整数m,n,表示查询的起始与终止士兵编号;如果是字符串ADD则后面跟的两个整数I,A(1<=I<=N,1<=A<=100),表示第I个士兵新增杀敌数为A.
输出格式
对于每次查询,输出一个整数R表示第m号士兵到第n号士兵的总杀敌数,每组输出占一行
样例输入
5 6
1 2 3 4 5
QUERY 1 3
ADD 1 2
QUERY 1 3
ADD 2 3
QUERY 1 2
QUERY 1 5
样例输出
6
8
8
20
示例代码
#include<iostream>
#include<algorithm>
using namespace std;
int M, N, a[1000000], aa[1000000];
struct Zhiling {
int m;
int n;
string q;
};
struct Zhiling b[100000];
int main() {
while (scanf("%d%d", &N, &M) != EOF) {//只要不是EOF
aa[0] = 0;
for (int i = 1; i <= N; i++) {
cin >> a[i];
aa[i] = aa[i - 1] + a[i];//前缀和
}
for (int i = 1; i <= M; i++) {
cin >> b[i].q >> b[i].m >> b[i].n;
}
for (int i = 1; i <= M; i++) {
if (b[i].q[0] == 'Q') {//如果是查询杀敌数
cout << aa[b[i].n] - aa[b[i].m - 1] << endl;
}
else {//如果是修改杀敌数
for (int j = b[i].m; j <= N; j++) {
aa[j] += b[i].n;
}
}
}
}
return 0;
}