提交 e434a100 编写于 作者: 每日一练社区's avatar 每日一练社区

update algorithm exercises

上级 afd09fe6
#### 题目描述
一个字符串的非空子串是指字符串中长度至少为1 的连续的一段字符组成的串。
例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共7 个。
注意在计算时,只算本质不同的串的个数。
请问,字符串```0100110001010001```有多少个不同的非空子串?
#include <bits/stdc++.h>
using namespace std;
int main(){
set<string> s;
string str;
cin >> str;
for(int i = 0; i < str.size(); i ++)
for(int j = i; j < str.size(); j ++)
s.insert(str.substr(i, j - i + 1));
cout << s.size();
return 0;
}
\ No newline at end of file
public class Demo2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
sc.close();
Set<String> set = new HashSet<String>();
for (int i = 0; i < str.length() + 1; i++) {
for (int j = i + 1; j < str.length() + 1; j++) {
set.add(str.substring(i, j));
}
}
System.out.println(set.size());
}
}
如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?
```
5650 4542 3554 473 946 4114 3871 9073 90 4329
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899
1486 5722 3135 1170 4014 5510 5120 729 2880 9019
2049 698 4582 4346 4427 646 9742 7340 1230 7683
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649
6701 6645 1671 5978 2704 9926 295 3125 3878 6785
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074
689 5510 8243 6114 337 4096 8199 7313 3685 211
```
\ No newline at end of file
#include<iostream>
using namespace std;
int main(){
int count2=0,count5=0;
int num;
for(int i=0;i<100;i++){
cin>>num;
while(num%5==0){
count5++;
num/=5;
}
while(num%2==0){
count2++;
num/=2;
}
}
int ans=count2<count5?count2:count5;
cout<<ans;
return 0;
}
import java.math.BigInteger;//输入的时候,记住要一行输所有的100个数字,
//并且每个数字之间要空一格,只能空一格,这样才能计算出答案。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String s;
BigInteger a, b;
Scanner cin = new Scanner(System.in);
s = cin.nextLine();
String[] num = s.split(" ");
BigInteger ans = new BigInteger("1");
for (int i = 0; i < num.length; i++) {
ans = ans.multiply(BigInteger.valueOf(Integer.valueOf(num[i])));
}
System.out.println(ans);
}
}
\ No newline at end of file
给定 N 个整数 A1,A2,…AN。
请你从中选出 K 个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009 的余数。
注意,如果 X<0, 我们定义 X 除以 1000000009 的余数是负(−X)除以 1000000009 的余数,即:0−((0−x)%1000000009)
#### 输入格式
第一行包含两个整数 N 和 K。
以下 N 行每行一个整数 Ai。
#### 输出格式
输出一个整数,表示答案。
#### 数据范围
```
1≤K≤N≤105,
−105≤Ai≤105
```
#### 输入样例1:
```
5 3
-100000
-10000
2
100000
10000
```
#### 输出样例1:
```
999100009
```
#### 输入样例2:
```
5 3
-100000
-100000
-2
-100000
-100000
#### 输出样例2:
-999999829
```
\ No newline at end of file
#include<iostream>
#include <vector>
#include<algorithm>
using namespace std;
int main(){
int n,k;
long long ans;
cin>>n>>k;
vector<long long>num;
for(int i=0;i<n;i++){
int temp;
cin>>temp;
num.push_back(temp);
}
sort(num.begin(),num.end());
if(k%2!=0){
ans=num.back();
k=k-1;
num.pop_back();
}
else
ans=1;
while(k>0){
if((num[0]*num[1])>num.at(num.size()-1)*num.at(num.size()-2)){
ans=ans*num[0]*num[1]%1000000009;
num.erase(num.begin(),num.begin()+1);
}
else{
ans=ans*num.at(num.size()-1)*num.at(num.size()-2)%1000000009;
num.pop_back();
num.pop_back();
}
k-=2;
}
cout<<ans;
return 0;
}
import java.util.Scanner;
import java.math.*;
public class Main {
private static String s;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n, k;
n = cin.nextInt();
k = cin.nextInt();
s = cin.next();// 不读回车和空格的方式读入
BigDecimal sum = dfs(k, n - 1);
System.out.println(sum);
}
// id是乘号的序号(从左到右1~k);
// dfs(id,r)表示:第id号乘号安放在在第r个空(一共n-1个空)时的最大值
static BigDecimal dfs(int id, int r) {
if (id == 1) {// 安放最后一个(递归概念1号就是递归出口)
BigDecimal sum = BigDecimal.valueOf(0);
for (int i = r; i >= 1; i--) {
BigDecimal x = BigDecimal.valueOf(0);
BigDecimal y = BigDecimal.valueOf(0);
for (int k1 = 0; k1 <= i - 1; k1++) {
char c = s.charAt(k1);
x = x.multiply(BigDecimal.valueOf(10)).add(BigDecimal.valueOf(Integer.parseInt(String.valueOf(c))));
}
for (int k2 = i; k2 <= r; k2++) {
char c = s.charAt(k2);
y = y.multiply(BigDecimal.valueOf(10)).add(BigDecimal.valueOf(Integer.parseInt(String.valueOf(c))));
}
sum = sum.max(x.multiply(y));
}
return sum;
}
BigDecimal maxn = BigDecimal.valueOf(0);
for (int i = r; i >= id; i--) {
BigDecimal temp = dfs(id - 1, i - 1);
BigDecimal tt = BigDecimal.valueOf(0);
for (int kk = i; kk <= r; kk++) {
char c = s.charAt(kk);
tt = tt.multiply(BigDecimal.valueOf(10)).add(BigDecimal.valueOf(Integer.parseInt(String.valueOf(c))));
}
maxn = maxn.max(tt.multiply(temp));
}
return maxn;
}
}
\ No newline at end of file
```
   B    DEF
A + —- + ——–- = 10
   C    GHI
```
这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
\ No newline at end of file
#include<stdio.h>
#include<stdbool.h>
int ans = 0;
int nums[10];
bool visited[10];
void judge()
{
int i;
if (nums[0] + (double)nums[1]/nums[2] + (double)(nums[3] *100 + nums[4]* 10 + nums[5])/(nums[6]*100 + nums[7]*10 + nums[8]) == 10)
{
printf("%d + %d/%d + %d%d%d/%d%d%d",nums[0],nums[1],nums[2],nums[3],nums[4],nums[5],nums[6],nums[7],nums[8]);
printf("\n");
ans++;
}
}
void dfs(int index)
{
if(index >= 9)
{
judge();
return ;
}
int i;
for(i=1;i<10;i++)
{
if(visited[i] == false)
{
visited[i] = true;
nums[index] = i;
dfs(index + 1);
visited[i] = false;
}
}
}
int main()
{
dfs(0);
printf("%d\n",ans);
return 0;
}
public class SuanShiJieFa {
static int num = 0;
public static void f1(int a[], int k) {
double q;
double w;
double e;
if (k == a.length - 1) {
q = a[0];
w = a[1] * 1.00 / a[2];
e = (a[3] * 100 + a[4] * 10 + a[5]) * 1.00 / (a[6] * 100 + a[7] * 10 + a[8]);
if (q + w + e == 10) {
num++;
}
}
for (int i = k; i < a.length; i++) {
{
int temp = a[i];
a[i] = a[k];
a[k] = temp;
}
f1(a, k + 1);
{
int temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
}
public static void main(String[] args) {
int a[] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
f1(a, 0);
System.out.println(num);
}
}
\ No newline at end of file
对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”。
![](https://img-blog.csdn.net/20160125091111485)
上图表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数。可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正。
# include <stdio.h>
void bigmul(int x, int y, int r[])
{
int base = 10000;
int x2 = x / base;
int x1 = x % base;
int y2 = y / base;
int y1 = y % base;
int n1 = x1 * y1;
int n2 = x1 * y2;
int n3 = x2 * y1;
int n4 = x2 * y2;
r[3] = n1 % base;
r[2] = n1 / base + n2 % base + n3 % base;
r[1] = n2 / base + n3 / base + n4 % base; // 填空
r[0] = n4 / base;
r[1] += r[2] / base; // 填空
r[2] = r[2] % base;
r[0] += r[1] / base;
r[1] = r[1] % base;
}
int main(int argc, char* argv[])
{
int x[] = {0,0,0,0};
bigmul(87654321, 12345678, x);
printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);
return 0;
}
\ No newline at end of file
#### 问题描述
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
#### 输入格式
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
#### 输出格式
输出一个整数,表示大臣J最多花费的路费是多少。
#### 样例输入1
```
5
1 2 2
1 3 1
2 4 5
2 5 4
```
#### 样例输出1
```
135
```
#### 输出格式
```
大臣J从城市4到城市5要花费135的路费。
```
\ No newline at end of file
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))//不能mem(double)
#define ll long long
const double eps=3e-8;
const int mod=10;
const int maxn=10005;//最好数量范围大一点;1e4+5 && long long
vector<int>ed[maxn];//存储每个点的邻接点
ll edge[maxn][maxn];//存储每个边值
ll dis[maxn];//存储bfs中从node点开始的路径长
ll sum=0;
int bfs(int node){
mem(dis,-1);
queue<int>que;
que.push(node);
int ans=node;
dis[node]=0;
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=0;i<ed[now].size();i++){
int temp=ed[now][i];
if(dis[temp]<0){
dis[temp]=dis[now]+edge[now][temp];
if(dis[temp]>sum){
ans=temp;
sum=dis[temp];
}
que.push(temp);
}
}
}
return ans;
}
int main(){
freopen("in4.txt","r",stdin);
int n,a,b;
ll c;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%lld",&a,&b,&c);
ed[a].push_back(b);
ed[b].push_back(a);
edge[a][b]=c;
edge[b][a]=c;
}
int starta=1;
int endnode,startnode;
sum=0;
endnode=bfs(starta);
sum=0;
startnode=bfs(endnode);
///cout<<endnode<<" "<<startnode<<" "<<sum<<endl;
double ans=sum*(sum+1.0)/2+10.0*sum;
printf("%.0f\n",ans);
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
//动态链表ArrayList
class Vertex {
ArrayList<Integer> V = new ArrayList();
}
class Edge {
ArrayList<Integer> E = new ArrayList();
}
public class Main {
final static int INF = 0X3f3f3f3f;
final static int maxn = 100000;// 开100000数组才过,我r
static Vertex v[] = new Vertex[maxn + 5];// v[i]存储与i相邻接的节点
static Edge e[] = new Edge[maxn + 5];// e[i]存储与i相邻接的边,与v[i]一一对应
static boolean vis[] = new boolean[maxn + 5];// 防止重复访问
static int dis[] = new int[maxn + 5];// 存储原始节点到各节点的dfs距离
static void init(int n)// 初始化
{
for (int i = 0; i < n; i++) {
v[i] = new Vertex();
e[i] = new Edge();
}
}
static void dfs(int a) {
int len = v[a].V.size();
vis[a] = true;
for (int i = 0; i < len; i++)// 遍历邻接节点
{
int j = v[a].V.get(i);
if (!vis[j] && e[a].E.get(i) != INF) {
vis[j] = true;
dis[j] = dis[a] + e[a].E.get(i);
// System.out.println(a+" "+j+" "+dis[j]);
dfs(j);
vis[j] = false;// 回溯
}
}
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
init(n);
for (int i = 0; i < n - 1; i++) {
int a = cin.nextInt();
int b = cin.nextInt();
int d = cin.nextInt();
v[a - 1].V.add(b - 1);// 节点从零开始
e[a - 1].E.add(d);
v[b - 1].V.add(a - 1);
e[b - 1].E.add(d);
}
Arrays.fill(vis, false);
Arrays.fill(dis, INF);
dis[0] = 0;
dfs(0);// 第一次遍历
long max = -1;
int temp = -1;
for (int i = 0; i < n; i++) {
if (dis[i] > max) {
max = dis[i];
temp = i;
}
}
// System.out.println(temp);
Arrays.fill(vis, false);
Arrays.fill(dis, INF);
dis[temp] = 0;
dfs(temp);// 第二次遍历
long ans = -1;// 防止越界
for (int i = 0; i < n; i++) {
if (dis[i] > ans) {
ans = dis[i];
temp = i;
}
}
// System.out.println(ans);
ans = ans * 10 + ans * (ans + 1) / 2;// 如果ans是int的话,有可能越界
System.out.println(ans);
cin.close();
}
}
\ No newline at end of file
中国古代文献中,曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。
它的前几项是:```0、2、4、8、12、18、24、32、40、50 …```
其规律是:对偶数项,是序号平方再除2,奇数项,是序号平方减1再除2。
以下的代码打印出了大衍数列的前 100 项。
\ No newline at end of file
#include <stdio.h>
int main()
{
int i;
for (i = 1; i < 20; i++)
{
if (i % 2 == 0)
printf("%d ", i * i / 2);
else
printf("%d ", (i * i - 1) / 2);
}
printf("\n");
}
\ No newline at end of file
public class Main {
public static void main(String[] args) {
for (int i = 1; i < 100; i++) {
if (i % 2 == 0) // 填空 //i%2==0偶数项
System.out.println(i * i / 2);
else// 奇数项
System.out.println((i * i - 1) / 2);
}
}
}
\ No newline at end of file
#### 问题描述
小蓝给学生们组织了一场考试,卷面总分为 分,每个学生的得分都是一个 到 的整数。
请计算这次考试的最高分、最低分和平均分。
#### 输入格式
输入的第一行包含一个整数 ,表示考试人数。
接下来 行,每行包含一个 至 的整数,表示一个学生的得分。
#### 输出格式
输出三行。
第一行包含一个整数,表示最高分。
第二行包含一个整数,表示最低分。
第三行包含一个实数,四舍五入保留正好两位小数,表示平均分。
#### 样例输入
```
80
92
56
74
88
99
10
```
#### 样例输出
```
99
10
71.29
```
\ No newline at end of file
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int sum=0;
int top=0;
int low=100;
int score;
for(int i=0;i<n;i++){
cin>>score;
if(score>top)top=score;
if(score<low)low=score;
sum+=score;
}
printf("%d\n%d\n%.2lf",top,low,(sum*1.0/n));
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
//成绩分析(利用集合)
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList<Integer> list = new ArrayList<>();
int n = scan.nextInt();
double sum = 0;
for (int i = 0; i < n; i++) {
list.add(scan.nextInt());
sum = sum + list.get(i);
}
Collections.sort(list);
System.out.println(Collections.max(list));
System.out.println(Collections.min(list));
System.out.println(String.format("%.2f", sum / n));
scan.close();
}
}
#### 问题描述
编写一个程序,建立了一条单向链表,每个结点包含姓名、学号、英语成绩、数学成绩和C++成绩,并通过链表操作平均最高的学生和平均分最低的学生并且输出。
#### 输入格式
输入n+1行,第一行输入一个正整数n,表示学生数量;接下来的n行每行输入5个数据,分别表示姓名、学号、英语成绩、数学成绩和C++成绩。注意成绩有可能会有小数。
#### 输出格式
输出两行,第一行输出平均成绩最高的学生姓名。第二行输出平均成绩最低的学生姓名。
#### 样例输入
```
2
yx1 1 45 67 87
yx2 2 88 90 99
```
#### 样例输出
```
yx2
yx1
```
\ No newline at end of file
#include<iostream>
using namespace std;
int main(){
struct student{
string xm;
int xh;
double yy;
double sx;
double cpp;
};
student a[1000];
int n;
double sum=0,min=301,max=0;
string mins,maxs;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i].xm>>a[i].xh>>a[i].yy>>a[i].sx>>a[i].cpp;
sum=a[i].yy+a[i].sx+a[i].cpp;
if(min>sum){
min=sum;mins=a[i].xm;
}
if(max<sum){
max=sum;maxs=a[i].xm;
}
}
cout<<maxs<<endl<<mins;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String Max = ""; // 成绩最高
String Min = ""; // 成绩最低
double maxavg = Integer.MIN_VALUE; // 最大平均值
double minavg = Integer.MAX_VALUE; // 最小平均值
for (int i = 0; i < n; i++) {
String Name = scanner.next(); // 姓名
String Id = scanner.next(); // 学号
int English = scanner.nextInt(); // 英语
int Mathematics = scanner.nextInt(); // 数学
int Cplus = scanner.nextInt(); // C++
double Avg = (English + Mathematics + Cplus) / 3; // 平均成绩
if (maxavg < Avg) { // 最大平均值<平均成绩
Max = Name; // 最大值=姓名
maxavg = Avg; // 最大平均值=平均成绩
}
if (minavg > Avg) { // 最小平均值>平均成绩
Min = Name; // 最小值=姓名
minavg = Avg; // 最小平均值=平均成绩
}
}
System.out.println(Max); // 输出成绩最高者
System.out.println(Min); // 输出成绩最低者
}
}
小明在X星球的城堡中发现了如下图形和文字:
```
rank=3
*
* *
* *
* * * *
rank=5
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
ran=6
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
```
小明开动脑筋,编写了如下的程序,实现该图形的打印。
#include<cstdio>
#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); //(填空)处理顶上三角形
f(a, rank-1, row+w/2, col); //f(0,5,16,0) //处理左下角
f(a, rank-1, row+w/2, col+w);//f(0,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,6,0,0);
f(a, 4, 0, 0);
for(i=0; i<N; i++){
for(j=0; j<N; j++) printf("%c",a[i][j]);
printf("\n");
}
return 0;
}
\ No newline at end of file
给出菱形的边长,在控制台上打印出一个菱形来。
为了便于比对空格,我们把空格用句点代替。
当边长为8时,菱形为:
```
*
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*
```
\ No newline at end of file
public class Main {
public static void main(String[] args) {
f(8);
}
public static void f(int n) {
String s = "*";
for (int i = 0; i < 2 * n - 3; i++)
s += ".";
s += "*";
String s1 = s + "\n";
String s2 = "";
for (int i = 0; i < n - 1; i++) {
s = "." + s.substring(0, s.length() - 3) + "*"; // 填空
s1 = s + "\n" + s1;
s2 += s + "\n";
}
System.out.println(s1 + s2);
}
}
\ No newline at end of file
X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。
每块金属原料的外形、尺寸完全一致,但重量不同。
金属材料被严格地堆放成金字塔形。
```
7
5 8
7 8 8
9 2 7 2
8 1 4 9 1
8 1 8 8 4 1
7 9 6 1 4 5 4
5 6 5 5 6 9 5 6
5 5 4 7 9 3 5 5 1
7 5 7 9 7 4 7 3 3 1
4 6 4 5 5 8 8 3 2 4 3
1 1 3 3 1 6 6 5 5 4 4 2
9 9 9 2 1 9 1 9 2 9 5 7 9
4 3 3 7 7 9 3 6 1 3 8 8 3 7
3 6 8 1 5 3 9 5 8 3 8 1 8 3 3
8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9
8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4
2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9
7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6
9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3
5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9
6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4
2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4
7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6
1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3
2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8
7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9
7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6
5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
```
其中的数字代表金属块的重量(计量单位较大)。
最下一层的X代表30台极高精度的电子秤。
假设每块原料的重量都十分精确地平均落在下方的两个金属块上,
最后,所有的金属块的重量都严格精确地平分落在最底层的电子秤上。
电子秤的计量单位很小,所以显示的数字很大。
工作人员发现,其中读数最小的电子秤的示数为:```2086458231```
请你推算出:读数最大的电子秤的示数为多少?
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll maxn=1e6+50;
double a[1050][1050];
int main()
{
for(ll i=1;i<=29;i++)
{
for(ll j=1;j<=i;j++)
{
scanf("%lf",&a[i][j]);
}
}
for(ll i=1;i<=29;i++)
{
for(ll j=1;j<=i;j++)
{
a[i+1][j]+=(0.5*a[i][j]);
a[i+1][j+1]+=(0.5*a[i][j]);
}
}
double minn=1000000000,maxx=-1;
for(ll i=1;i<=30;i++)
{
maxx=max(maxx,a[30][i]);
minn=min(minn,a[30][i]);
printf("%lf\n",a[30][i]);
}
printf("%lf\n",maxx*2086458231/minn);
}
public class Main {
static long[][] data = new long[30][30];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long factor = 1;/// 计量单位的数因子
for (int i = 0; i < 30; i++) {
factor <<= 1;
}
for (int i = 0; i < 29; ++i)// 输入数据放入二维数组(前29)
{
for (int j = 0; j <= i; ++j) {
long a = sc.nextLong();
data[i][j] = a * factor;
}
}
for (int i = 0; i < 29; ++i) {
for (int j = 0; j <= i; ++j) {
long half = data[i][j] / 2;
data[i + 1][j] += half;
data[i + 1][j + 1] += half;
}
}
Arrays.sort(data[29]);
System.out.println(data[29][0]);
System.out.println(data[29][29]);
System.out.println(data[29][29] / (data[29][0] / 2086458231));
}
}
X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。
....
那么最终派往W星的观察团会有多少种国别的不同组合呢?
#### 输入格式
第一行N,以下N行代表N个国家最多可派出人数Ai。
#### 输出格式
最多多少种派法ANS,ANS为一个整数。
#### 输出规模
```
1<N<10000
1<AI<10000
```
#### 示例输入
```
6
4
2
2
1
1
3
```
示例输出
```
101
```
#include <iostream>
using namespace std;
int a[10000],N,i,ans = 0;
void findAns(int a[],int start,int An)//国家可派出数组a,当前派出第start国家,已经组合An人
{
if(start == N)//找到最后一个国家后
{
if(An == 5) ans++;//如果组合人数An等于派出人数5;
return;
}
for(i = 0;i<=a[start];i++)//派出第n个国家人数的人数,需检查人数是否满足规范
{
findAns(a,start+1,An+i);//查找下一个国家,记录已经组合数An
}
}
int main()
{
//输入规模及数据
cin>>N;
for(i = 0;i < N;i++)
{
cin>>a[i];
}
findAns(a,0,0);
cout<<ans<<endl;
return 0;
}
public class Main {
// 遍历到第k个国家,还有n个空位
public static void f(int[] a, int k, int n, String s) {
if (k == a.length) {// 超过国家数
if (n == 0)// 选满5个人
System.out.println(s);
return;
}
if (n < 0)
return;
String s2 = s;
// 第k个国家出i个人
for (int i = 0; i <= a[k]; i++) {// a[k]表示第k个国家最多可以派出的人数
f(a, k + 1, n - i, s2);// 轮到下一个国家,空缺人数少了i个
s2 += (char) (k + 'A');
}
}
public static void main(String[] args) {
int[] a = { 4, 2, 2, 1, 1, 3 };
f(a, 0, 5, "");// 5是指选5个人
}
}
\ No newline at end of file
小明最近喜欢搭数字积木,
一共有10块积木,每个积木上有一个数字,0~9。
搭积木规则:
每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。
最后搭成4层的金字塔形,必须用完所有的积木。
下面是两种合格的搭法:
```
0
1 2
3 4 5
6 7 8 9
0
3 1
7 5 2
9 8 6 4
```
请你计算这样的搭法一共有多少种?
//搭积木 768
#include<bits/stdc++.h>
using namespace std;
int row = 4,col;
int seq[5][8];//下标从1开始
int tmp[11];
int cnt = 0;
bool used[10];
void change(){//将一维数组转换成二维数组
int cur = 1;
for(int i = 1; i <= row ; ++i){
for(int j = 1; j <= i; ++j){
seq[i][j] = tmp[cur ++];
}
}
}
bool judge(){//判断二维数组是否符合条件
for(int i = 1; i <= row - 1; ++i){
for(int j = 1; j <= i ; ++j){
if(seq[i][j] > seq[i + 1][j] || seq[i][j] > seq[i + 1][j + 1]) return false;
}
}
return true;
}
int ans = 0;
void dfs(int idx){
//idx:当前要操作的下标(从1开始)
if(idx == 11){
change();
if(judge()){
cnt++;
return ;
}
return ;
}
for(int i = 0; i <= 9; ++i){
if(!used[i]){
tmp[idx] = i;
used[i] = true;
dfs(idx + 1);
used[i] = false;
}
}
}
int main(){
memset(used,false,sizeof(used));
dfs(1);
cout<<cnt<<endl;
return 0;
}
\ No newline at end of file
import java.util.Arrays;
public class Text13 {
static int h = 0;
public static void main(String[] args) {
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
permute(array, 0);
}
// 验证
public static int[] text(int[] array) {
boolean a = array[0] < array[1] && array[0] < array[2];
boolean b = array[1] < array[3] && array[1] < array[4];
boolean c = array[2] < array[4] && array[2] < array[5];
boolean d = array[3] < array[6] && array[3] < array[7];
boolean e = array[4] < array[7] && array[4] < array[8];
boolean f = array[5] < array[8] && array[5] < array[9];
if (a & b & c & d & e & f) {
return array;
}
return null;
}
// 递归排列
public static void permute(int[] array, int start) {
if (start == array.length - 1 && text(array) != null) {
System.out.println(++h + " " + Arrays.toString(text(array)));
}
for (int i = start; i < array.length; i++) {
swap(array, start, i);
permute(array, start + 1);
swap(array, start, i);
}
}
// 交换
public static void swap(int[] array, int start, int end) {
int telp = array[start];
array[start] = array[end];
array[end] = telp;
}
}
#### 问题描述
x星球有26只球队,分别用 a ~ z 的26个字母代表。他们总是不停地比赛。
在某一赛段,哪个球队获胜了,就记录下代表它的字母,这样就形成一个长长的串。
国王总是询问:获胜次数最多的和获胜次数最少的有多大差距?
(当然,他不关心那些一次也没获胜的,认为他们在怠工罢了)
#### 输入格式
一个串,表示球队获胜情况(保证串的长度<1000)
#### 输出格式
要求输出一个数字,表示出现次数最多的字母比出现次数最少的字母多了多少次。
#### 样例输入1
```
abaabcaa
```
#### 样例输出1
```
4
```
#### 提示
```
a 出现 5 次,最多;c 出现1次,最少。
5 - 1 = 4
```
#### 样例输入2
```
bbccccddaaaacccc
```
#### 样例输出2
```
6
```
\ No newline at end of file
#include <stdio.h>
#include <string.h>
int main() //计数排序
{
char s[1000];
scanf("%s", &s);
int len = strlen(s); //获取字符串s的长度
int helper[256] = { 0 }; //ascll范围在0~255之间(包括0和255)
int max = 0, min = len;
for (int i = 0; i < len; i++)
{
helper[s[i]]++; //计数
}
for (int i = 0; i < 256; i++)
{
if (helper[i] > max)
{
max = helper[i];
}
if (helper[i] < min&&helper[i] != 0)
{
min = helper[i];
}
}
printf("%d\n", max - min);
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Map<Character, Integer> map = new HashMap<Character, Integer>();
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
for (int i = 0; i < str.length(); i++) {
char key = str.charAt(i);
// 如果没有这个键,则添加键并赋值为1
if (!map.containsKey(key)) {
map.put(key, 1);
}
// 否则获取当前值,自增1
else {
int value = map.get(str.charAt(i));
map.put(key, ++value);
}
}
// 使用HashMap的方法values(),取出所有的Value集合构造List
List<Integer> sorted = new ArrayList<Integer>(map.values());
// 然后使用Collections.sort排序
Collections.sort(sorted);
// 用最大的值减去最小的值,得到差
int difference = sorted.get(sorted.size() - 1) - sorted.get(0);
System.out.print(difference);
}
}
\ No newline at end of file
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
#include <iostream>
using namespace std;
int num[5][1010]={0};
int dp(int k,int n)
{
int res=10000;
if(n==0)
return 0;
if(k==1)
return n;
if(num[k][n])
return num[k][n];
for(int i=1;i<=n;i++)
{
res=min(res,max(dp(k-1,i-1),dp(k,n-i))+1);
}
num[k][n]=res;
return res;
}
int main()
{
cout<<dp(3,1000)<<endl;
return 0;
}
\ No newline at end of file
public class Main {
public static void main(String[] args) {
System.out.println(solution1(1000, 3));
}
public static int solution1(int n, int c) {
if (c == 1) {
return n;
}
int[][] dp = new int[n + 1][c + 1];
for (int i = 1; i < n + 1; i++) {
dp[i][1] = i;// 当只有一部手机时,其测试次数为楼层数,因为只能一层一层测试
}
for (int i = 1; i < n + 1; i++) {
for (int j = 2; j < c + 1; j++) {
int min = Integer.MAX_VALUE;// 表示int数据类型的最大取值数:2 147 483 647
for (int k = 1; k < i + 1; k++) {
min = Math.min(min, Math.max(dp[k - 1][j - 1], dp[i - k][j]));
}
dp[i][j] = min + 1;
}
}
return dp[n][c];
}
}
把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。
\ No newline at end of file
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<char>vc1;
int i;
for(i=0;i<2014;i++)
vc1.push_back('a'+(i%19));
while(vc1.size()!=1)
{
vector<char>vc2;
cout<<vc1.size()<<endl;
for(i=1;i<vc1.size();i+=2)
vc2.push_back(vc1[i]);
vc1.assign(vc2.begin(),vc2.end());
cout<<vc1.size()<<endl;
}
cout<<vc1[0]<<endl;
return 0;
}
\ No newline at end of file
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String string = "", string1 = "";
for (int i = 0; i < 2014; i++) {
string += (char) ('a' + (i % 19));
}
while (string.length() != 1) {
for (int i = 0; i < string.length(); i++) {
if (i % 2 == 1) {
string1 += string.charAt(i);
}
}
string = string1;
string1 = "";
}
System.out.println(string);
}
}
\ No newline at end of file
美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。
一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:“我年龄的立方是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,他当时到底有多年轻。
#include<iostream>
using namespace std;
int main() {
for (int i = 11; i < 35; i++) {
int i1 = i * i * i;
int i2 = i * i1;
if ((i1 >= 1000 && i1 < 10000)&& (i2 >= 100000 && i2 < 1000000))
cout << i << " " << i1 << " " << i2 << endl;
}
return 0;
}
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static boolean judge(int x) {
int a = x * x * x;
int b = x * x * x * x;
boolean vis[] = new boolean[10];
if (a < 1000 || a > 9999)
return false;
if (b < 100000 || b > 999999)
return false;
while (a > 0) {
vis[a % 10] = true;
a /= 10;
}
while (b > 0) {
vis[b % 10] = true;
b /= 10;
}
for (int i = 0; i < 10; i++)
if (!vis[i])
return false;
return true;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
for (int i = 1; i <= 1000; i++) {
if (judge(i)) {
System.out.println(i);
break;
}
}
}
}
小明有n颗石子,按顺序摆成一排。他准备用胶水将这些石子粘在一起。每颗石子有自己的重量,如果将两颗石子粘在一起,将合并成一颗新的石子,重量是这两颗石子的重量之和。
为了保证石子粘贴牢固,粘贴两颗石子所需要的胶水与两颗石子的重量乘积成正比,本题不考虑物理单位,认为所需要的胶水在数值上等于两颗石子重量的乘积。
每次合并,小明只能合并位置相邻的两颗石子,并将合并出的新石子放在原来的位置。
现在,小明想用最少的胶水将所有石子粘在一起,请帮助小明计算最少需要多少胶水。
测试样例
输入
```
3
3 4 5
```
输出
```
47
```
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int numv[maxn];
int v[maxn];
int dfs(int idx){
if(idx==0)
return 0;
if(idx==1)
return v[0]*v[1];
int max_,a=0x3f3f3f,b=0x3f3f3f3f,c=0;
if(idx>=2)
a=(v[idx]*v[idx-1]+dfs(idx-2)+numv[idx-2]*(v[idx]+v[idx-1])); //与左边粘
b=v[idx]*numv[idx-1]+dfs(idx-1); //与左边不粘
c=min(a,b);
return c;
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&v[i]);
if(i==0) numv[i]=v[i];
numv[i]=numv[i-1]+v[i];
}
printf("%d",dfs(n-1));
}
\ No newline at end of file
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[1010];
int[][] dp = new int[1010][1010];
int[][] jiaoshui = new int[1010][1010];
// dp[i][j]代表从第i个到第j个石头合并的重量
// jiaoshui[i][j]代表从第i个到第j个石头合并的胶水量
for (int i = 1; i <= n; i++) {
a[i] = in.nextInt();
dp[i][i] = a[i];
}
// for (int i=1; i<n; i++) {
// for(int j=i+1; j<=n; j++) {
// dp[i][j]=dp[i][j-1]+a[i];
// }
// }
// r是循环的范围,要从两个石头合并开始算,因为只有相邻的才能合并
for (int r = 2; r <= n; r++) {
// 循环起始点,j就是从i向后r个范围的点j
for (int i = 1; i <= n - r + 1; i++) {
int j = i + r - 1;
jiaoshui[i][j] = Integer.MAX_VALUE;
// 这个是代表的用的哪个范围合并的石头,最后要加起来
int temp1 = 0;
// 这个是取两个相邻石头差值最大的拼凑
// 好比一共10个石头
// 差值小:一堆分五块 5*5=25
// 差值大: 一个1块一个9块 1*9=9
// 胶水量形成了鲜明的对比,差值大的省胶水
int tempmax = -1;
for (int k = i; k < j; k++) {
if (tempmax < Math.abs(dp[i][k] - dp[k + 1][j])) {
// 保存从哪里分开(哪两堆石头合并起来的)
temp1 = k;
// dp[i][j]代表从第i个到第j个石头合并有重
dp[i][j] = dp[i][k] + dp[k + 1][j];
// 找差值最大的进行合并省胶水
tempmax = Math.abs(dp[i][k] - dp[k + 1][j]);
jiaoshui[i][j] = dp[i][k] * dp[k + 1][j];
}
}
// 如果jiaoshui[i][i]表示的是一个石头,一个石头粘连在一起是不需要胶水的,这里要跳过
if (i != temp1)
jiaoshui[i][j] += jiaoshui[i][temp1];
if (temp1 + 1 != j)
jiaoshui[i][j] += jiaoshui[temp1 + 1][j];
}
}
// 1-n粘连需要的最小胶水
System.out.println(jiaoshui[1][n]);
}
}
#### 问题描述
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
#### 输入格式
要求程序首先输入一个整数N(N<100)表示后面数据行数。
接着读入N行数据。
每行数据长度不等,是用空格分开的若干个(不大于100个)正整数(不大于100000),请注意行内和行末可能有多余的空格,你的程序需要能处理这些空格。
每个整数代表一个ID号。
#### 输出格式
要求程序输出1行,含两个整数m n,用空格分隔。
其中,m表示断号ID,n表示重号ID
#### 样例输入1
```
2
5 6 8 11 9
10 12 9
```
#### 样例输出1
```
7 9
```
#### 样例输入2
```
6
164 178 108 109 180 155 141 159 104 182 179 118 137 184 115 124 125 129 168 196
172 189 127 107 112 192 103 131 133 169 158
128 102 110 148 139 157 140 195 197
185 152 135 106 123 173 122 136 174 191 145 116 151 143 175 120 161 134 162 190
149 138 142 146 199 126 165 156 153 193 144 166 170 121 171 132 101 194 187 188
113 130 176 154 177 120 117 150 114 183 186 181 100 163 160 167 147 198 111 119
```
#### 样例输出2
```
105 120
```
\ No newline at end of file
//代码3
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int ans[10005];
char str[100001];
int main()
{
int n;
cin>>n;
int i,k=0;
getchar();
for(i=0; i<n; i++)
{
gets(str);
char *p;
p=strtok(str," ");
ans[k++]=atoi(p);
while(p)
{
p=strtok(NULL," ");
if(p)
ans[k++]=atoi(p);
}
}
sort(ans,ans+k);
int ans1,ans2;
for(i=0; i<k-1; i++)
{
if(ans[i+1]-ans[i]==2)
{
ans1=ans[i]+1;
}
if(ans[i+1]==ans[i])
ans2=ans[i];
}
cout<<ans1<<" "<<ans2;
}
\ No newline at end of file
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
sc.nextLine();
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < N; i++) {
String s = sc.nextLine();
String str[] = s.split(" ");
for (int j = 0; j < str.length; j++) {
list.add(Integer.parseInt(str[j]));
}
}
Collections.sort(list);
int m = 0, n = 0;
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i) + 2 == list.get(i + 1))
m = list.get(i) + 1;
if (list.get(i).equals(list.get(i + 1)))
n = list.get(i);
}
System.out.println(m + " " + n);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册