2021-01-12

編程学习历程

一、哈学院冬令营day2

A - The puzzle
Kayaking is playing a puzzle game containing n different blocks. He marks the blocks with integers from 1 to n, which show the blocks’ original positions. Each time he can exchange two blocks and he wants to know how many times he needs at least to restore the puzzle.

Input

The input starts with one line contains exactly one positive integer which is the number of test cases.
Each test case contains two lines.
The first line contains an integer, which indicates the number of puzzle pieces.
The second line contains n different integers, the i-th number means the mark of the block in the i-th position.

Output
For each test case, output one line with one number represents the minimum operations.

Sample Input
2
4
2 3 4 1
4
2 1 4 3

Sample Output
3
2
想法:一开始想用冒泡排序,但是超时了,后来看了一下题解
超时代码:

#include <stdio.h>
#include <iostream>
using namespace std;
int a[100000], b[10000];

int main() {
	int k, n, temp, flag = 0;
	cin >> k;
	for (int i = 1; i <= k; i++) {
		cin >> n;
		for (int j = 1; j <= n; j++) {
			cin >> a[i];
		}
		for (int j = 1; j <= n; j++) {
			for (int m = j; m <= n - 1; m++) {
				if (a[j] > a[m + 1]) {
					temp = a[j];
					a[j] = a[m + 1];
					a[m + 1] = temp;
					flag++;
				}
			}
		}
		b[i] = flag;
		flag = 0;
	}
	for (int i = 1; i <= k; i++) {
		cout << b[i] << endl;;
	}
	return 0;
}

正确代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n;
		scanf("%d", &n);
		int a[100010];
		int vis[100010] = {0};
		for (int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
		}
		int res = 0;
		for (int i = 1; i <= n; i++) {
			int tmp = a[i], count = 0;
			while (!vis[tmp]) {
				vis[tmp] = 1;
				tmp = a[tmp];
				count++;
			}
			if (count > 0)
				res += (count - 1);
		}
		printf("%d\n", res);
	}
	return 0;
}

B - Overflow
Kayaking is a naughty boy and he loves to play water. One day, Kayaking finds a bucket. The bottom area of the bucket is S and the height is H. Initially, there is V volume water in the bucket. What makes Kayaking happy is that there are N cube woods beside the bucket. The side length of the i-th cube woods is L[i] and its density is P[i]. Kayaking wants to put all the cube woods to the bucket. And then he will put a cover at the top of the bucket. But CoffeeDog doesn’t allow unless Kayaking can tell CoffeeDog the height of the water in the bucket after Kayaking put all the cuboid woods to the bucket. Could you help him?
It is guaranteed that the cube woods aren’t overlapping. And after putting the wood to the bucket, the bottom of the wood is parallel to the bottom of the bucket.
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N denoting the number of cube woods.
Then comes N line. Each line has two real numbers L[i] and P[i].
The last line contains three integers S, H and V.
Output
For each test cases, print a single line containing one real number—the height of the water in the bucket(the number should be rounded to the second digit after the decimal point).
Sample Input
1
2
1 1.5
1 0.5
5 100 25
Sample Output
5.30
想法:这是一道物理题,可以知道,正方体块放入水中,会根据其密度上浮或者下沉,这决定了正方体块没在水中的体积,这个体积即排水体积,进而影响水位高低。首先明确的是几个物理公式,pv=g,即质量=体积*密度,然后是水的密度是1。就可以做这题了。
我们不关注放进去的过程,什么如果一个个放进去水位会不断抬高,进而一些较大体积的木块会因为水位的抬高而增大浮力,什么水位本身就比一些正方体块低,因此无视密度而只关乎水位的之类的事情都不管,忽略掉,就直接将所有块放入水中。

然后就会出现,一些密度大于等于水的,完全沉底,那么排水体积直接增加正方体块完整体积。若密度小于水,因为水的密度是1,质量和体积数值上相等,因此排出水的体积即正方体块的完整质量。这样根据质量和体积就求出了完整的排水体积,即水的增加体积,用求和得到的体积除以底面积即可得到水位高度,注意如果水位漫过了容器高度,那么结果就是容器高度。
代码如下:

#include <stdio.h>
#include <iostream>
using namespace std;
int T, n;

int main() {
	cin >> T;
	while (T--) {
		double s, h, v, l, p, sum = 0;
		cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> l >> p;
			if (p >= 1) {
				sum = sum + ((l * l * l) );
			} else {
				sum += (l * l * l * p);
			}
		}
		cin >> s >> h >> v;
		sum += v;
		sum /= s;
		printf("%.2f\n", sum < h ? sum : h);
	}
	return 0;
}
```今天的蒟蒻有进步了一些;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值