目录
1.算式900
题目描述
(□□□□-□□□□)*□□=9001
其中的小方块代表 0 ~ 9 的数字,这 10 个方块刚好包含了 0 ~ 9 中的所有数字。 注意:0 不能作为某个数字的首位。
小明经过几天的努力,终于做出了答案!如下:
(5012-4987)*36=9001
用计算机搜索后,发现还有另外一个解,本题的任务就是:请你算出这另外的一个解。
注意:输出格式需要与示例严格一致; 括号及运算符号不要用中文输入法; 整个算式中不能包含空格。
思路
枚举0~9全排列进行判断,注意每个数首位不能为0
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
bool vis[11];
int p[11];
int f(int l,int r){
int sum=0;
for(int i=l;i<=r;i++){
sum=sum*10+p[i];
}
return sum;
}
void dfs(int u ){
if(u==10){
int a=f(0,3);
int b=f(4,7);
int c=f(8,9);
if((a-b)*c==900&&a/1000!=0&&b/1000!=0&&c/10!=0){
cout<<a<<" "<<b<<" "<<c<<endl;
}
return;
}
for(int i=0;i<10;i++){
if(!vis[i]){
vis[i]=1;
p[u]=i;
dfs(u+1);
vis[i]=0;
p[u]=0;
}
}
}
int main(){
dfs(0);
return 0;
}
2、谈判
题目描述
在很久很久以前,有 n 个部落居住在平原上,依次编号为 1 到 n。第 i 个部落的人数为 t[i]。
有一年发生了灾荒。年轻的政治家小蓝想要说服所有部落一同应对灾荒,他能通过谈判来说服部落进行联合。
每次谈判,小蓝只能邀请两个部落参加,花费的金币数量为两个部落的人数之和,谈判的效果是两个部落联合成一个部落(人数为原来两个部落的人数之和)。
思路
贪心,每次都合并人数最少的两个部落,最后的花费一定也是最小的
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e4+10 ;
int n;
int a[N];
int cost;//花费
int main(){
cin>>n;
for(int i=0;i<n;i++ )cin>>a[i];
sort(a,a+n);
for(int i=1;i<n;i++){
a[i]=a[i]+a[i-1];
cost=cost+a[i];
sort(a,a+n);
}
cout<<cost;
return 0;
}
3、幸运数
题目描述
幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的"筛法"生成。
首先从 1 开始写出自然数 1,2,3,4,5,6,⋯
1 就是第一个幸运数。
我们从 2 这个数开始。把所有序号能被 2 整除的项删除,变为:
1 3 5 7 9⋯
把它们缩紧,重新记序,为:
13579⋯
这时,3 为第 2个幸运数,然后把所有能被 3 整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被 3 整除!!删除的应该是 5,11, 17…
此时 7 为第 3 个幸运数,然后再删去序号位置能被 7 整除的( 19,39…)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, ⋯
思路
一开始不知道怎么筛,后来看了大佬的题解
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e6 + 10 ;
int n, m;
bool st[N];//标记i位置的数是否被筛去
int ans;
int main() {
cin >> n >> m; //[n,m]区间
for (int i = 2; i <= m; i++) { //
if (!st[i]) {
int cnt = 0; //记录新序列的数的下标
for (int j = 1; j <= m; j++) { //遍历1~m的序列
if (!st[j]) {
cnt++;
if (cnt % i == 0) st[j] = 1; //被筛掉的数置为1
}
}
}
}
int ans = 0;
for (int i = n + 1; i < m; i++) if (!st[i]) ans++;
cout << ans;
return 0;
}
4、123
题目描述
小蓝发现了一个有趣的数列,这个数列的前几项如下:
1, 1, 2, 1, 2, 3, 1, 2, 3, 4, ⋯
小蓝发现,这个数列前 1 项是整数 1,接下来 2 项是整数 1 至 2,接下来 3 项是整数 1 至 3,接下来 4 项是整数 1 至 4,依次类推。
小蓝想知道,这个数列中,连续一段的和是多少。
输入描述
输入的第一行包含一个整数 T,表示询问的个数。
接下来 T 行,每行包含一组询问,其中第 ii 行包含两个整数 li 和 ri,表示询问数列中第li 个数到第 ri 个数的和。
输出描述
输出 T 行,每行包含一个整数表示对应询问的答案。
输入
3
1 1
1 3
5 8
输出
1
4
8
思路
这题不怎么会做,待后续补充