洛谷 [LGR-079]洛谷 11 月月赛 I & MCOI Round 3 Div.2 正方&村国

正方

题目

在这里插入图片描述

思路

要让四个三角形面积比为a​ ​ : b : ​c : d,就是要让E到四条边的距离比为a : b : c : d但是同时又要满足组成一个四边形,就要满足a,b,c,d中任意两个数相加的和与另外两个数的和相等,同时又要考虑重复的情况。

做法:全排列a,b,c,d的位置,两两组合,用vis去除重复即可

代码

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
void swapp(ll &a , ll &b){
	ll tmp;
	tmp = a;	a = b;	b = tmp;
}
ll a[5];
ll vis[50][5] , siz;
ll ans;
void dfs(int x){
	if(x == 3){
		if(!(a[0] + a[1] == a[2] + a[3]))return;
		for(int i = 1 ; i <= siz ; i++){
			bool check = true;
			for(int j = 0 ; j < 4 && check ; j++)
				if(vis[i][j] != a[j])check = false;
			if(check)return;
		}
		ans++;
		++siz;
		for(int j = 0 ; j < 4 ; j++)
			vis[siz][j] = a[j];
		return;
	}
	for(int i = x ; i < 4 ; i++){
		swapp(a[x] , a[i]);
		dfs(x + 1);
		swapp(a[x] , a[i]);
	}
}
int main(){
	int q;
	cin >> q;
	while(q--){
		cin >> a[0] >> a[1] >> a[2] >> a[3];
		ans = 0;
		siz = 0;
		dfs(0);
		cout << ans << endl;
	}
	return 0;
}

村国

抗议——毒瘤数据!!!

题目

在这里插入图片描述

思路

1.无脑暴力(模拟)(30分)

2.正解:

选出所有a里面a[k]最小的前提下最小的k,在k的子节点中找k2使得,a[k2]最大的前提下k2最小,最后的答案一定是k或k2中的一个(详见下,不做详细证明):

		m -= a[k] - a[k2];
		int ans;
		if(m < 0)	ans = k;
		else{
			if((m % 2) == 0)
				ans = k < k2 ? k : k2;
			else
				ans = k > k2 ? k : k2;
		}

你以为这就结束了吗?

还有一个问题:n=1的情况

k必为1,那k2呢?,为空

如果不做特判,就有可能输k2(具体要看m的奇偶性)这就是有时候自己手动测n=1的数据没出错的原因

更毒瘤的是,5个数据点中,4个都有至少一组数据的n为1,这就是大多数人苦苦卡在15分,对拍了几百组数据找不到问题的原因

听取WA声一片

在这里插入图片描述

代码

暴力(#2.cpp)

#include <iostream>
#include <cstdio>
#include <cstring>
#define nn 2000010
#define ll long long
using namespace std;
ll read(){
	ll re = 0 , sig = 1;
	char c = getchar();
	while(c < '0' || c > '9'){
		if(c == '-')sig = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
		re = (re << 1) + (re << 3) + c - '0',
		c = getchar();
	return re;
}
struct ednode{
	int u , nxt;
}ed[nn];
int head[nn];
void addedge(int u , int v){
	static int top = 1;
	if(u == 0 && v == 0){top = 1;return;}
	ed[top].u = v , ed[top].nxt = head[u] , head[u] = top;
	top++;
}
int n;
ll m;
ll a[nn];
int main(){
	int T = read();
	while(T--){
		memset(ed , 0 , sizeof(ed));
		memset(head , 0 , sizeof(head));
		addedge(0 , 0);
		
		n = read() , m = read();
		for(int i = 1 ; i <= n ; i++)
			a[i] = read();
		for(int i = 1 ; i < n ; i++){
			int u = read() , v = read();
			addedge(u , v);
			addedge(v , u);
		}
		int maxn = 0 , k;
		for(int i = 1 ; i <= m ; i++){
			maxn = 0;
			for(int j = 1 ; j <= n ; j++)
				if(a[j] > maxn)
					maxn = a[j] , k = j;
			for(int j = head[k] ; j ; j = ed[j].nxt){
				++a[ed[j].u];
			}
		}
		maxn = 0;
		for(int i = 1 ; i <= n ; i++)
				if(a[i] > maxn)
					maxn = a[i] , k = i;
			
		printf("%d\n" , k);
	}
	return 0;
}

正解(#2+.cpp)

#include <iostream>
#include <cstdio>
#include <cstring>
#define nn 2000010
#define ll long long
using namespace std;
ll read(){
	ll re = 0 , sig = 1;
	char c = getchar();
	while(c < '0' || c > '9'){
		if(c == '-')sig = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
		re = (re << 1) + (re << 3) + c - '0',
		c = getchar();
	return re;
}
struct ednode{
	int u , nxt;
}ed[nn * 2];
int head[nn];
void addedge(int u , int v){
	static int top = 1;
	if(u == 0 && v == 0){top = 1;return;}
	ed[top].u = v , ed[top].nxt = head[u] , head[u] = top;
	top++;
}
int n;
ll m;
ll a[nn];
int main(){
//	freopen("input.txt" , "r" , stdin);
	int T = read();
	while(T--){
		memset(ed , 0 , sizeof(ed));
		memset(head , 0 , sizeof(head));
		addedge(0 , 0);
		
		n = read() , m = read();
		for(int i = 1 ; i <= n ; i++)
			a[i] = read();
		for(int i = 1 ; i < n ; i++){
			int u = read() , v = read();
			addedge(u , v);
			addedge(v , u);
		}
		if(n == 1){
			printf("1\n");
			continue;
		}
		ll maxn = 0 ;
		int k = 0 , k2 = 0;
		for(int i = 1 ; i <= n ; i++)
			if(maxn < a[i])
				maxn = a[i] , k = i;
		maxn = 0;
		for(int i = head[k] ; i ; i = ed[i].nxt){
			if(a[ed[i].u] > maxn || (a[ed[i].u] == maxn && ed[i].u < k))
				maxn = a[ed[i].u] , k2 = ed[i].u;
		}
		m -= a[k] - a[k2];
		int ans;
		if(m < 0)	ans = k;
		else{
			if((m % 2) == 0)
				ans = k < k2 ? k : k2;
			else
				ans = k > k2 ? k : k2;
		}
			
		printf("%d\n" , ans);
	}
	return 0;
}

随机数生成(#2random.cpp)

#include <bits/stdc++.h>
#define ull unsigned long long
#define int unsigned int
using namespace std;
int random(int r , int l = 1){
	if(r == l)return l;
	return (long long)rand() * rand() % (r - l) + l;
}
ull llrandom(ull r , ull l = 1){
	if(r == l)return l;
	return (long long)random(1 << 29) * random(1 << 29) % (r - l) + l;
}
void output(ull x , char c = ' '){
	if(x >= 10)output(x / 10 , 0);
	putchar(x % 10 + 48);
	if(c != 0)putchar(c);
}
signed main(){
//	freopen("input.txt" , "w" , stdout);
	srand((unsigned)time(0));
	int t = 10;
	printf("%d\n" , t);
	while(t--){
		int n = 20;
		output(n) , output(llrandom(100) , '\n');
		for(int i = 1 ; i <= n ; i++)
			output(random(20));
		putchar('\n');
		for(int i = 2 ; i <= n ; i++)
			output(random(i - 1)) , output(i , '\n');
	}
	return 0;
}

对拍控制程序(#2compare.cpp)

#include <bits/stdc++.h>
using namespace std;
int main(){
	int cnt = 0;
	while(true){
		cnt++;
		printf("No.%d\n" , cnt);
		system("#2random.exe > input.txt");
		puts("random\tfinished");
		
		system("#2fro.exe < input.txt > output.txt");
		puts("#2fro\tfinished");
		
		system("#2.exe < input.txt > output2.txt");
		puts("#2\t\tfinished");
		
		if(system("fc output.txt output2.txt")){
			cout << "WA\n";
			system("start input.txt");
			return 0;
		}
	}
	return 0;
}

括号

AK月赛的大佬的博客

金牌

从没做过交互题,貌似CSP也不考

AK月赛的大佬的博客

posted @ 2020-11-11 11:07  追梦人1024  阅读(66)  评论(0编辑  收藏  举报