yp寒假训练一

19年东北四省省赛

做了J G C

补了E H

J签到题

G

题意:

给n个正方形的两个斜对角点坐标,问最小的移动可以重叠(移动上下左右一格)

思路:

一开始想的是中心pos移动,但是可能有小数,而且半径长度不知,可能有包含关系。

然后发现题目没说一定要某一个正方形移动的最小步数,那之间转换为点在面里面的移动最小,取中间的两个上下斜对角坐标就行了

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include<set>
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 #define mem(a,b) memset(a,b,sizeof(a))
12 using namespace std;
13 #define ll long long
14 #define inf 0x3f3f3f3f
15 #define mod 998244353
16 const int maxn=1e5+10;
17 struct node{
18     int x,y,xx,yy;
19 }a[maxn];
20 int t,n;
21 int x[maxn<<1],y[maxn<<1];
22 int main()
23 {
24     scanf("%d",&t);
25     while(t--){
26         scanf("%d",&n);
27         int xt=0,yt=0;
28         for(int i=0;i){
29             scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].xx,&a[i].yy);
30             x[xt++]=a[i].x,x[xt++]=a[i].xx;
31             y[yt++]=a[i].y,y[yt++]=a[i].yy;
32         }
33         sort(x,x+xt);
34         sort(y,y+yt);
35         int zx=x[xt/2],zy=y[yt/2];
36         ll sum=0;
37         for(int i=0;i){
38             if(zxa[i].xx){
39                 sum+=(ll)min(abs(a[i].x-zx),abs(a[i].xx-zx));
40             }
41             if(zya[i].yy){
42                 sum+=(ll)min(abs(a[i].y-zy),abs(a[i].yy-zy));
43             }
44         }
45         printf("%lld\n",sum);
46     }
47     return 0;
48 }
View Code

 

C

题意:

给n条直线,问有多少两两相交的线,重叠也算相交的线

思路:

总量n*(n-1)/2-平行的数量

一开始算斜率,但因为斜率的精确度,wa,然后想了用gcd或者用逆元

最后用了map存y/x的最小分数yy和xx,在特判一下重叠的

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include<set>
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 #define mem(a,b) memset(a,b,sizeof(a))
12 using namespace std;
13 #define ll long long
14 #define inf 0x3f3f3f3f
15 #define mod 998244353
16 const int maxn=1e5+10;
17 int n,t;
18 ll a,b,c,d;
19 ll gcd(ll a,ll b){
20     return b==0?a:gcd(b,a%b);
21 }
22 struct node{
23     ll x,y;
24     node(){}
25     node(ll xx,ll yy):x(xx),y(yy){}
26     bool operator<(const node &b)const
27     {
28         if(x==b.x)
29             return y<b.y;
30         else
31             return x<b.x;
32     }
33 };
34 struct node1{
35     ll x,y,chong;
36     node1(){}
37     node1(ll xx,ll yy,ll cc):x(xx),y(yy),chong(cc){}
38     bool operator<(const node1 &b)const
39     {
40         if(x==b.x){
41             if(y==b.y){
42                 return chong<b.chong;
43             }
44             return y<b.y;
45         }
46         else
47             return x<b.x;
48     }
49 };
50 mapmp;
51 mapcd;
52 int main()
53 {
54     scanf("%d",&t);
55     while(t--){
56         scanf("%d",&n);
57         ll zong=(ll)n*(n-1)/2;
58         for(int i=0;i){
59             scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
60             ll xx=a-c,yy=b-d;
61             ll gd=gcd(xx,yy);
62             ll x=xx/gd,y=yy/gd;
63             ll f=x*b+y*a;
64             mp[node(x,y)]++;
65             zong-=mp[node(x,y)];
66             cd[node1(x,y,f)]++;
67             zong+=cd[node1(x,y,f)];
68         }
69         printf("%lld\n",zong);
70         mp.clear(),cd.clear();
71     }
72     return 0;
73 }
View Code

 

E

题意:

给n个点,n-1条边,每条边都有权重,每个边形成一个最小生成树,形成线图

思路:

算每个点的贡献值,这个点的出度小于二,无贡献,大于二,就是相邻的边加一起,在最小的那个边*(相邻边数-2)

 1 #include
 2 #include
 3 #include
 4 #include<string>
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 const int maxn=100010;
14 struct node
15 {
16     int v,w;
17     node(){}
18     node(int n,int m):v(n),w(m){}
19     bool operator < (const node &r)const{
20         return w<r.w;
21     }
22 };
23 vectorG[maxn];
24 int main()
25 {
26     int T;
27     scanf("%d",&T);
28     while(T--){
29         int n;
30         scanf("%d",&n);
31         for(int i=1;i<=n;i++)G[i].clear();
32         for(int i=1;i<=n-1;i++){
33             int u,v,w;
34             scanf("%d%d%d",&u,&v,&w);
35             G[u].push_back(node(v,w));
36             G[v].push_back(node(u,w));
37         }
38         ll ans=0;
39         for(int i=1;i<=n;i++){
40             sort(G[i].begin(),G[i].end());
41             int minn=0x3f3f3f3f;
42             int degree=G[i].size();
43             for(int j=0;j){
44                 ans+=G[i][j].w;
45                 minn=min(minn,G[i][j].w);
46             }
47             ans+=(ll)minn*(degree-2);
48         }
49         printf("%lld\n",ans);
50     }
51     return 0;
52 }
View Code

 

H:

https://www.cnblogs.com/luoyugongxi/p/12191649.html

你可能感兴趣的:(yp寒假训练一)