碎碎念
我快两点了才想起来下午比赛
一个多小时写了五份就签上两题的道
然后一直在调那个chess,优化搜索…
快结束了才意识到可以打表
好多题都只能过样例
合并序列,枚举k,暴力统计不知道为啥会WA,题意里的k到底代表什么意思至今没看懂。。。
tree我感觉暴力枚举c(n,2)加lca大概lgn应该是可以卡5e5的数据的啊,可是怎么调都TLE
A The warm love problem AC
题意:给出桌子的四只脚,判断能否放置一个矩形桌面在上面
这个结论有点猜测的意味,,不过一遍就过了也没花多少时间
//四点在一个矩形面上
//四个数排序,间距为1,判断是否能构成平行四边形,会不会WA?,过了就好。。。
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int a[5];
struct point{ double x, y; }pp[4];
double TwoPointDiatance(point a, point b){//计算两点之间的距离
return sqrt(pow((a.x - b.x), 2) + pow((a.y - b.y), 2));
}
int main(){
int T; cin>>T;
while(T--){
for(int i = 1; i <= 4; i++)cin>>a[i];
sort(a+1,a+5);
int ok = 1;
for(int i = 2; i <= 4; i++)
if(a[i]!=a[1]){ok=0;break;}
if(ok){
cout<<"YES\n";
continue;
}
//
for(int i = 1 ; i <= 4; i++){
pp[i].x = (double)i; pp[i].y = (double)a[i];
}
double s1, s2, s3, s4;
s1 = TwoPointDiatance(pp[1], pp[3]);
s2 = TwoPointDiatance(pp[1], pp[2]);
s3 = TwoPointDiatance(pp[4], pp[2]);
s4 = TwoPointDiatance(pp[3], pp[4]);
if(s1==s3 && s2==s4 && s1!=0){
cout<<"YES\n";
continue;
}
cout<<"NO\n";
}
return 0;
}
D 合并序列 WA
拿到题面的想法就是合并果子小根堆小根堆,然后直接枚举嘿嘿
TLE也就认了,,WA是什么鬼。。
别看了我没过。。
题解貌似让我长点脑子,,二分一下就可以小根堆了。。
//对于给定的k最小代价,类似于合并果子,小根堆维护
//枚举k,暴力统计,会不会TLE
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
//priority_queue<int, vector<int>, greater<int> >q;
vector<int>v;
int main(){
int n, T;
cin>>n>>T;
for(int i = 1; i <= n ; i++){
int x; cin>>x; v.push_back(x);
}
int ansk = n;
for(int kk = 2; kk <= n; kk++){
priority_queue<int, vector<int>, greater<int> >q;
for(int i = 0; i < n; i++)q.push(v[i]);
int num = 0;
for(int i = 0; i < n; i++){
int tmp = 0;
for(int j = 1; j <= kk; j++){
tmp += q.top(); q.pop();
if(q.size()==0)break;
}
//cout<<" "<<q.size()<<" "<<tmp<<endl;
num += tmp;
q.push(tmp);
if(q.size()==1)break;
}
//cout<<kk<<" "<<num<<endl;
if(num<=T){
ansk = kk;
break;
}
}
cout<<ansk<<"\n";
return 0;
}
E&F 题解
E感觉很可做,但是题意min(x,tot)没看懂,不知道要求啥
F大概直接是不会做的
G chess AC
全场写的最蛋疼的一题,chess爆搜也是人才
开始深搜,记忆化vis二维4e5开不下换成set,甚至想换unordered_set还是一直TLE。
从最开始的枚举n,m二维搜到后来从1,1开始搜。。。
可是吧,感觉题面这么简洁经典的一道题,怎么可能这么奇怪的做法,还unordered_set都出来了。。。
然后我突然意识到,除了一些特殊情况走不满,其他的可以走满,这就是象棋的马走日
我记得马是可以不重复地走满象棋盘,所以应该只有部分小情况不行
什么情况下不行呢,这个就可以暴力了。。
最后搜出来去掉m==1,2,3和n==1,2,3,的情况,全部都是n*m
吐血了,优化了一下午的搜索,最后是个打表题。
我说为什么那么多人都过了,我怎么这么菜。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
int n, m, cnt, ans;
//int vis[45010][45010];
/*
set<pair<int,int> >vi;
const int dx[] = {-2, -2, 2, 2, -1, -1, 1, 1};
const int dy[] = {-1, 1, -1, 1, -2, 2, -2, 2};
void dfs(int x, int y){
if(x<1||x>n||y<1||y>m)return ;
//if(vis[x][y])return ;
if(vi.count(make_pair(x,y)))return ;
cnt++;
//vis[x][y] = 1;
vi.insert(make_pair(x,y));
for(int i = 0; i < 8; i++){
dfs(x+dx[i],y+dy[i]);
}
}
*/
int main(){
cin>>n>>m;
if(n==3&&m==3){
cout<<8<<endl;
return 0;
}
if(n==1||m==1){
cout<<1<<endl;
return 0;
}
if(n==2){
int as;
if(m%2==0)as = m/2;
else as = (m+1)/2;
cout<<as<<endl;
return 0;
/*
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
vi.clear(); cnt = 0;
dfs(i,j);
ans = max(ans,cnt);
}
}
cout<<ans<<"\n";
return 0;
*/
}
if(m==2){
int as;
if(n%2==0)as = n/2;
else as = (n+1)/2;
cout<<as<<endl;
return 0;
}
cout<<n*m<<endl;
return 0;
}
H CBX and children AC
题意:大概就是n个小朋友,身高小于1/2的可以躲在高个的后面,求最少看到的人数
直接二分答案了,一圈一个小朋友,,也没花多少时间的样子?(雾)
//5e5的数据大概nlogn而且常数容易卡
//排个序试试二分答案?会TLE吗
#include<iostream>
#include<algorithm>
using namespace std;
int n, h[500010];
bool cmp(int x, int y){return x>y;}
bool check(int x){//cbx只找到x个孩子是否成立
if(x<n-x)return false;
int ok = 1;
for(int i = x+1; i <= n; i++){
if(h[i]*2>h[i-x]){
ok = 0; break;
}
}
//cout<<x<<" "<<ok<<'\n';
if(ok)return true;
else return false;
}
int main(){
cin>>n;
for(int i = 1; i <= n; i++)cin>>h[i];
sort(h+1,h+n+1,cmp);
int l = 1, r = n;
while(l < r){
int mid = l+r>>1;
if(check(mid))r = mid;
else l = mid+1;
}
//cout<<l<<" "<<r<<endl;
cout<<l<<'\n';
return 0;
}
J Tree TLE
//LCA求树上路径logn,枚举方案C(n,2),2e5的数据应该能卡吧
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define maxn 200010
using namespace std;
int n,q;
struct edge{ int next,v; }edges[maxn*2];
int cnt, head[maxn];
void init(){ memset(head,-1,sizeof(head)); cnt=0; }
void addedge(int u,int v){
edges[cnt].next=head[u];
edges[cnt].v=v;
head[u]=cnt++;
}
int dep[maxn];
int f[maxn][21];
void dfs(int u, int fa){
dep[u] = dep[fa]+1;
for(int i = 0; i <= 19; i++)
f[u][i+1]=f[f[u][i]][i];
for(int i = head[u]; i != -1; i = edges[i].next){
int v = edges[i].v;
if(v==fa)continue;
f[v][0] = u;
dfs(v,u);
}
}
int lca(int x, int y){
if(dep[x]<dep[y])swap(x,y);
for(int i = 20; i >= 0; i--){
if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
}
for(int i = 20; i >= 0; i--){
if(f[x][i]!=f[y][i]){
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
}
int m, a[maxn], b[maxn];
int main(){
scanf("%d%d",&n,&m);
init();
for(int i = 1; i <= n-1; i++){
int x, y; scanf("%d%d",&x,&y);
addedge(x,y); addedge(y,x);
}
dfs(1,0);
for(int i = 1; i <= m; i++){
scanf("%d%d",&a[i],&b[i]);
}
int ans = 0;
for(int i = 1; i <= m; i++){
for(int j = i+1; j <= m; j++){
int tmp1 = dep[a[i]]+dep[a[j]]-2*dep[lca(a[i],a[j])];
int tmp2 = dep[b[i]]+dep[b[j]]-2*dep[lca(b[i],b[j])];
ans = max(ans, tmp1+tmp2);
}
}
cout<<ans<<"\n";
return 0;
}
补全BC、I、K
C题考试没时间看了,结束看了题面感觉很可做,但是没时间了
B题又臭又长的英文题再见。
I题又臭又长的英文题再见。
K题题又臭又长的英文题再见。