2019 东北四省赛部分题解 The 13th Chinese Northeast Collegiate Programming Contest
比赛链接 :https://codeforces.com/gym/102220
J题: 按题意模拟就行
#include<bits/stdc++.h>
#define bug1(g) cout<<"test: "<<g<<endl
#define bug2(g,i) cout<<"test: "<<g<<" "<<i<<endl
#define bug3(g,i,k) cout<<"test: "<<g<<" "<<i<<" "<<k<<endl
#define bug4(a,g,i,k) cout<<"test: "<<a<<" "<<g<<" "<<i<<" "<<k<<endl
using namespace std;
typedef long long ll;
ll n;
int t;
ll a[20];
ll x;
int main()
{ios::sync_with_stdio(0);cin>>t;while(t--){cin>>n;cin>>x;ll maxx=x*3;for (int i =2;i<=n;i++){cin>>a[i];maxx=max(maxx,a[i]+1);}if(maxx&1) maxx++;cout<<maxx<<endl;}return 0;
}
G题: 给N个矩形,每个矩形每次可以上下左右移动一格,问至少几次可以使得有一个方格被所有矩形覆盖
按照出题人的做法
证明在这 https://www.cnblogs.com/xidian-mao/p/7819928.html
代码如下
#include<bits/stdc++.h>
#define bug1(g) cout<<"test: "<<g<<endl
#define bug2(g,i) cout<<"test: "<<g<<" "<<i<<endl
#define bug3(g,i,k) cout<<"test: "<<g<<" "<<i<<" "<<k<<endl
#define bug4(a,g,i,k) cout<<"test: "<<a<<" "<<g<<" "<<i<<" "<<k<<endl
using namespace std;
typedef long long ll;
const int maxn=100005;
int n;
struct node
{int xl,xr,yl,yr;
}a[maxn];
int x[maxn*2],y[maxn*2];
int cntx,cnty;
ll sumx,sumy;
int t;
int main()
{//ios::sync_with_stdio(0);scanf("%d",&t);while(t--){scanf("%d",&n);cntx=cnty=1;sumx=sumy=0;for(int i =1;i<=n;i++){scanf("%d %d %d %d",&a[i].xl,&a[i].yl,&a[i].xr,&a[i].yr);sumx+=a[i].xr-a[i].xl;sumy+=a[i].yr-a[i].yl;x[cntx++]=a[i].xl;x[cntx++]=a[i].xr;y[cnty++]=a[i].yl;y[cnty++]=a[i].yr;}sort(x+1,x+cntx);sort(y+1,y+cnty);// bug2(cntx,cnty);--cntx;--cnty;ll xx=x[cntx/2],yy=y[cnty/2];ll ans=-sumx-sumy;for(int i =1;i<=n;i++){ans+=abs(a[i].xl-xx)+abs(xx-a[i].xr);ans+=abs(a[i].yl-yy)+abs(yy-a[i].yr);}printf("%lld\n",ans/2);}return 0;
}
除了中位数外,我们可以看出这个一维情况下,这个函数是个单峰函数,可以用三分分别求x,y的位置 然后再算总和
#include<bits/stdc++.h>
#define bug1(g) cout<<"test: "<<g<<endl
#define bug2(g,i) cout<<"test: "<<g<<" "<<i<<endl
#define bug3(g,i,k) cout<<"test: "<<g<<" "<<i<<" "<<k<<endl
#define bug4(a,g,i,k) cout<<"test: "<<a<<" "<<g<<" "<<i<<" "<<k<<endl
using namespace std;
typedef long long ll;
const int maxn=100005;
int n;
struct node
{int xl,xr,yl,yr;
}a[maxn];
int maxx[2],minn[2];
ll sum(int x,int ii)
{ll ans=0;if(ii==0) //xfor(int i=1;i<=n;i++){if(a[i].xl<=x&&x<=a[i].xr) continue;else if(x<a[i].xl) ans+=(ll)a[i].xl-x;else ans+=(ll)x-a[i].xr;}else{for(int i=1;i<=n;i++){if(a[i].yl<=x&&x<=a[i].yr) continue;else if(x<a[i].yl) ans+=(ll)a[i].yl-x;else ans+=(ll)x-a[i].yr;}}return ans;
}
int sery(int minn,int maxx,int i)
{int l =minn,r=maxx;int mid1,mid2;while(r-l>1){mid1=(l+r)/2;mid2=(mid1+r)/2;ll m1=sum(mid1,i),m2=sum(mid2,i);if(m1<m2)r=mid2;else l=mid1;}return sum(l,i)<sum(r,i)?l:r;
}
int t;
int main()
{//ios::sync_with_stdio(0);scanf("%d",&t);while(t--){scanf("%d",&n);maxx[0]=maxx[1]=-1;minn[0]=minn[1]=1e9+5;for(int i =1;i<=n;i++){scanf("%d %d %d %d",&a[i].xl,&a[i].yl,&a[i].xr,&a[i].yr);maxx[0]=max(maxx[0],a[i].xr);maxx[1]=max(maxx[1],a[i].yr);minn[0]=min(minn[0],a[i].xl);minn[1]=min(minn[1],a[i].yl);}int xx=sery(minn[0],maxx[0],0),yy=sery(minn[1],maxx[1],1);//bug2(xx,yy);cout<<sum(xx,0)+sum(yy,1)<<endl;}return 0;
}
C题: 给N条直线,求有多少对直线有交点(重合也算)
这题卡了精度,用斜率表示一直过不去 ,最后把直线写成AX+BY+C的形式 判断有多少直线重合 有多少重合或平行
假设一共有n条直线 xi条重合 yi条重合或平行 ans=n*(n-1)/2-yi*(yi-1)/2+xi*(xi-1)/2
重合要求A,B,C三个参数都一样,平行或重合只需要A,B一样就行,用map记录一下就ok了
#include<bits/stdc++.h>
#define bug1(g) cout<<"test: "<<g<<endl
#define bug2(g,i) cout<<"test: "<<g<<" "<<i<<endl
#define bug3(g,i,k) cout<<"test: "<<g<<" "<<i<<" "<<k<<endl
#define bug4(a,g,i,k) cout<<"test: "<<a<<" "<<g<<" "<<i<<" "<<k<<endl
using namespace std;
typedef long long ll;
const int maxn=100005;
struct node
{ll a,b,c;friend bool operator <(node a,node b){if(a.a!=b.a)return a.a<b.a;else if(a.b!=b.b) return a.b<b.b;return a.c<b.c;}
}a[maxn],b;
map<node,ll>mp1,mp2;
ll t,n;
int main()
{ios::sync_with_stdio(0);cin>>t;while(t--){ll xa,ya,xb,yb;mp1.clear();mp2.clear();cin>>n;for(int i =1;i<=n;i++){cin>>xa>>ya>>xb>>yb;yb=ya-yb;xb=xa-xb;ll k =__gcd(yb,xb);yb/=k;xb/=k;a[i].a=xb;a[i].b=-yb;a[i].c=yb*xa-xb*ya;if(a[i].a<0){a[i].a=-a[i].a;a[i].b=-a[i].b;a[i].c=-a[i].c;}b.a=a[i].a,b.b=a[i].b,b.c=0;++mp1[a[i]];++mp2[b];}ll ans=n*(n-1)/2;for(auto i =mp1.begin();i!=mp1.end();i++){ll tmp=i->second;ans+=tmp*(tmp-1)/2;}for(auto i =mp2.begin();i!=mp2.end();i++){ll tmp=i->second;ans-=tmp*(tmp-1)/2;}cout<<ans<<endl;}return 0;
}
H题:
队友写的,我也不会 贴个代码吧
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Point {ll x, y;bool operator<( Point const& b) const{return x<b.x||(x==b.x&&y<b.y);}
};
struct P {Point a, b;bool operator<( P const& b) const{return a < b.a ;}
};
map<P, int> mp;
map<Point, int> mp2;
ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a%b);
}
Point solve(Point &a,Point &b) {ll detx = b.x - a.x;ll dety = b.y - a.y;ll gcdd = gcd(detx, dety);
// cout << gcdd << endl;detx /= gcdd;dety /= gcdd;if (detx == 0) {a.y = b.y = 0;return Point{-1,-1};}if (dety == 0) {a.x = b.x = 0;return Point{0,0};}if (detx < 0) {detx = -detx;dety = -dety;}if (a.x >= 0) {ll tem = a.x / detx;a.x -= detx * tem;a.y -= dety * tem;}else {ll tem = -a.x / detx + 1;a.x += detx * tem;a.y += dety * tem;}if (b.x >= 0) {ll tem = b.x / detx;b.x -= detx * tem;b.y -= dety * tem;}else {ll tem = -b.x / detx + 1;b.x += detx * tem;b.y += dety * tem;}return Point{ detx,dety };
}
int main() {int T;scanf("%d", &T);while (T--) {ll ans = 0;mp.clear();mp2.clear();int n;scanf("%d", &n);for (int i = 0; i < n; i++) {ll x1, y1, x2, y2;scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2);Point a = Point{ x1,y1 };Point b = Point{ x2,y2 };Point p=solve(a, b);if (a < b) swap(a, b);P p2 = P{ a,b };ans += i - mp2[p] + mp[p2];mp2[p]++;mp[p2]++;}printf("%I64d\n", ans);}
}
B题:有n个糖果m种,每个糖果有两个值ai,bi 代表价值和种类,选择一些糖果,问选择糖果的价值和除以最大的同一种类数的值最大,第i种糖果至少选择l[i]次
枚举分母,选最大的分子就好了,预处理下选择x个糖果的情况下能获得的最大价值和(贪心先选择价值大的)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m;
ll t;
vector<ll>v[100005]; //每种中的价值有哪些
ll l[100005];
ll s,c;
ll ms[100005];
bool cmp(ll a,ll b)
{return a>b;
}
int main()
{ios::sync_with_stdio(0);cin>>t;while(t--){cin>>n>>m;for(int i =1;i<=m;i++){cin>>l[i];v[i].clear();}memset(ms,0,sizeof(ll)*(n+2));ll x,y;for(int i =1;i<=n;i++){cin>>x>>y;v[y].push_back(x);}ll maxx=-1;for(int i =1;i<=m;i++){maxx=max((ll)v[i].size(),maxx);sort(v[i].begin(),v[i].end(),cmp);ll tmp=0;for(int j = 0;j<v[i].size();j++){tmp+=v[i][j];if(j+1>=l[i]) //小于l[i]时不算在价值和里{ms[j+1]+=tmp;tmp=0;}}}ll as=-1,ac=1;for(ll i =1;i<=maxx;i++) //枚举同种最大数量{ms[i]+=ms[i-1];if(ms[i]!=0){s=ms[i];c=i;ll g=__gcd(s,c);s/=g;c/=g;if(as*c<ac*s){as=s;ac=c;}}}cout<<as<<"/"<<ac<<endl;}
}
E题: 给一颗树,问其线图的最小生成树
观察发现,原来的边权相当于线图的点权,线图的边权为两个结点的点权和. 而且对线图来说,他是一些完全图连接的,对完全图求最小生成树只需要将其余点都连向点权最小的点就行
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int n;
struct node
{ll v,w;node(ll a=0,ll b=0){v=a,w=b;}
} ;
vector<node>a[100005];
int main()
{ios::sync_with_stdio(0);cin>>t;while(t--){cin>>n;ll x,y,z;for(int i =1;i<=n;i++) a[i].clear();for(int i =1;i<=n-1;i++){cin>>x>>y>>z;a[x].push_back(node(y,z));a[y].push_back(node(x,z));}ll ans=0;for(int i =1;i<=n;i++){if(a[i].size()<2) continue;ll minn=0;for(int j =0;j<a[i].size();j++){if(a[i][j].w<a[i][minn].w) minn=j;}for(int j = 0;j<a[i].size();j++){if(j!=minn)ans+=a[i][j].w+a[i][minn].w;}}cout<<ans<<endl;}return 0;
}
2019 东北四省赛部分题解 The 13th Chinese Northeast Collegiate Programming Contest相关推荐
- The 15th Chinese Northeast Collegiate Programming Contest部分题解
The 15th Chinese Northeast Collegiate Programming Contest 目录 E. Easy Math Problem 题目思路 题目代码 I. Takea ...
- 【21.10.24】The 15th Chinese Northeast Collegiate Programming Contest题解
A. Matrix(组合数+数学) #include <bits/stdc++.h> using namespace std; #define mod 998244353 ll fac[1 ...
- The 15th Chinese Northeast Collegiate Programming Contest 题解(CCPC压力测试?
CCPC压力测试用了这套题,和一个队友一起搞了.初期签到还算比较顺利,还碰到了挺多有意思的题目,做的好爽,但还是犯了很多低级错误,对于杭电要时时刻刻关同步或者scanf,并且写代码还是要仔细些. A. ...
- 2018东北四省赛 Store The Matrix (矩阵)
2018东北四省赛 Store The Matrix (矩阵) 题目描述 Given a matrix M with r rows and c columns. It is obviously tha ...
- 2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 Apare_xzc
2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 by xzc,zx,lj 先 ...
- The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803
The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803 前言 题目 A. August B. Bills ...
- 「团队训练赛」The 14th Jilin Provincial Collegiate Programming Contest「ABCEFGJLM」
The 14th Jilin Provincial Collegiate Programming Contest A. Chord 题目描述: 给出C, C#, D, D#, E, F, F#, G, ...
- 2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016)题解
2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016) A - Artwork 题目描述: 给定N*M的网格,给出Q次 ...
- 2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program
2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program 题目链接 The kingdom of Z ...
- 2019浙江ACM省赛部分题解-ABDEFGHIJK
太菜了,心态炸了.QAQ A-Vertices in the Pocket() 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...
最新文章
- UTF-8与UTF-8 BOM
- 【组合数学】排列组合 ( 排列组合内容概要 | 选取问题 | 集合排列 | 集合组合 )
- AJAX-jQuery实现Ajax
- android4.0 菜单,Android 4.0.4系统曝光 增新Power菜单
- python监控网页更新_python监控网页更新
- java soap api操作和发送soap消息
- 浅谈UWB室内定位(二)
- 剑指offer——复习1:二叉树三种遍历方式的迭代与递归实现
- 中国SaaS市场将快速增长,或形成“小而美”林立格局
- string容器字符存取
- word文档字体段落文档格式标准设置(个人)
- Unity/C# 随机生成中文名
- 石柯送点 国足0:2不敌韩国小组第二出线
- bitly短网址v4版本的操作及sample code
- 【电信学】【2019.03】5G异构网络中的移动性管理
- 跨源通信--postMessage用法
- js运算保留后面两位小数
- 使用Python和OCR进行文档解析的完整代码演示(附代码)
- DL_POLY下并行计算出错问题解决
- 【IT情感】社会求助,也许你也曾有过的矛盾
热门文章
- ftp上传软件,推荐六款优秀的ftp上传软件
- 计算ip地址是否在同一网段
- viper4android资源分享,一步一步教你如何使4.42版本ROOT并且安装Viper4Android音效软件...
- 什么是计算机技术作文500字,关于电脑的作文500字
- 初探MySQL的语句之一
- 小成本创造高回报?这家企业的创新培训模式有点牛
- WEB-QTP随想录—李密的猜想
- “这个世界最可怕的不是很多人比你牛,而是比你牛的人比你还努力。”
- [Java教程 00] 计算机基础
- wps 邮件合并 mysql_笔记13 - 邮件合并