kotori和n皇后 and 疯狂的自我检索者(贪心)

148 阅读2分钟

kotori和n皇后

在这里插入图片描述 在这里插入图片描述

(1)测试数据

5
1 2
2 5
3 1
6 7
4 8
2
2
4

(2)关键思路

开4个set,分别存x、y、x + y、x - y; 遍历时,不断查询每个点是否在某个set里面存在,若不存在则分别加入4个set。否则证明和之前的皇后会攻击(把这个i皇后保留下来); 现在来说一下,为什么要保留这四个; x, or y集合中如果有已经相等的,说明是在同一行或者同一列(同行和同列会互相攻击); x - y存进集合中如果有已经相等的,说明在同45斜角(x1 - y1 == x2 - y2 => x1 - x2 == y1 - y2);(斜率为1 则 45度); x + y存进集合中如果有已经相等的,说明在同135斜角(x1 + y1 == x2 + y2 => x1 - x2 == - ( y1 - y2) );(斜率为-1 则为135度);

(3)实现代码

#include <bits/stdc++.h>
using namespace std;
int k; // 总共放置皇后的个数
int x, y;
set<int> s1, s2, s3, s4;
int t; // t次询问
int e; // 每次询问的皇后
 

int main() {
	cin >> k;
	// 若 idx 一直 == 0,说明它就一直不会攻击了
	// 找到“第一个” 
	int idx = 0; // 记录下是哪个皇后(i)放下后会互相攻击,那么它之前的i - 1个皇后的不会互相攻击的 
	for (int i = 1; i <= k; ++i){
		cin >> x >> y;
		if (s1.count(x) || s2.count(y) || s3.count(x - y) || s4.count(x + y)) {
			// 若是已经修改了,就不用再更新了 
			if (!idx) idx = i;
		}
		s1.insert(x);
		s2.insert(y);
		s3.insert(x - y) ;
		s4.insert(x + y);
	}
	cin >> t;
	while (t--) {
		cin >> e;
		if (idx && e >= idx) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}

疯狂的自我检索者

在这里插入图片描述

(1)关键思路

贪心的思想:未知的人都打5分,就是最大的了,未知的人都打1分,就是最小的了;

(2)测试数据

5 1
1 2 3 4

(3)代码

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

#define ll long long 

ll n, m;
double avMax;
double avMin;
int main () {
	ll x;
	
	cin >> n >> m;
	for (int i = 0; i < n - m; ++i) {
		cin >> x;
		avMax += x;
		avMin += x;
	} 
	
	for (int i = 0; i < m; ++i) {
		avMax += 5;
		avMin += 1;
	}
//	printf ("%.9lf ", avMin / n);
//	printf ("%.9lf", avMax / n);
	cout << fixed << setprecision(8) << avMin / n << ' ';
	cout << fixed << setprecision(8) << avMax / n << ' ';
	return 0;
}