洛谷 [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;
}
括号
金牌
从没做过交互题,貌似CSP也不考