2019 CCPC-Wannafly Winter Camp Day5(Div2, onsite)
solve 5/11
补题:7/11
Code:zz
Thinking :zz
题意:要在n*n的网格内画上一棵节点数为n树,使得没有边相交。
很好想的构造题,因为网格有n*n,足够大,所以结点1放在(1,1)的位置,与结点1相连的结点依次放在(2,1),(2,2)...的位子,依此类推。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> #include<bitset> #include<unordered_map> const int maxn = 0x3f3f3f3f; const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427; const double PI = 3.141592653589793238462643383279; using namespace std; struct s { int a,b; }z[2020],ans[2020]; vector<int>ve[2020]; int c[2020],hi[2020],d[2020]; int main(void) { int n,m,i,si,j,pos,cnt; while(~scanf("%d %d",&n,&m)) { memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); memset(hi,0,sizeof(hi)); for(i = 0;i <= n;i++) { ve[i].clear(); } for(i = 0;i < m;i++) { scanf("%d %d",&z[i].a,&z[i].b); ve[z[i].a].push_back(z[i].b); ve[z[i].b].push_back(z[i].a); } /*for(i = 1;i <= n;i++) { printf("%d: ",i); for(j = 0;j < ve[i].size();j++) { printf("%d ",ve[i][j]); } printf("\n"); }*/ queue<int>q; q.push(1); cnt = 0; c[1] = 1; d[1] = 1; hi[1] = 1; while(!q.empty()) { pos = q.front(); q.pop(); //c[pos] = cnt++; //printf("%d %d\n",c[pos],d[pos]); ans[pos].a = c[pos]; ans[pos].b = d[pos]; si = ve[pos].size(); //printf("pos = %d : ",pos); for(j = 0;j < si;j++) { //printf(" %d ",ve[pos][j]); if(!c[ve[pos][j]]) { c[ve[pos][j]] = c[pos] + 1; d[ve[pos][j]] = hi[c[ve[pos][j]]] + 1; hi[c[ve[pos][j]]]++; q.push(ve[pos][j]); } } //printf("\n"); } for(i = 1;i <= n;i++) { printf("%d %d\n",ans[i].a,ans[i].b); } } return 0; }
Code:zz
Thinking:zz
k很大,有1e9,但是n只有1e5,ai只有1e9,所以最多经过1e5*log(1e9)就能使所有数字变为0。用一个优先队列来存放数字,每次取出最大的一个并/2,然后放回,等到取出的数字为0或者操作次数用尽,就退出,然后把优先队列里的值加起来就好了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> #include<bitset> #include<unordered_map> const int maxn = 0x3f3f3f3f; const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427; const double PI = 3.141592653589793238462643383279; using namespace std; long long c[100010]; int main(void) { int n, m, i; long long ans, pos; while (~scanf("%d %d", &n, &m)) { priority_queue<long long>q; for (i = 0; i < n; i++) { scanf("%lld", c + i); q.push(c[i]); } while (m > 0) { pos = q.top(); //printf("%d\n",pos); q.pop(); if (pos == 1 || m == 0) { break; } pos /= 2; q.push(pos); m--; } ans = 0; while (!q.empty()) { pos = q.top(); q.pop(); ans += pos; } printf("%lld\n", ans); } return 0; }
搜索,待补,比赛的时候kk和pai爷提出了两个能ac的想法,但踏马的就是没写。
补题:zz
这是一道搜索题,可以先根据n和两个X之间的值的和枚举两个X的位置,再枚举两个X之间的数字可能的组合,可以通过预处理先把n=5,6,7时的所有和的情况全部处理出来,可以用二进制枚举达到这一点;其次,我还考虑了好多剪枝,在填上数字或者X的时候,判断行列是否有重复元素,如果填入的数字是在两个X之间的,判断能否用当前已有的两个X之间的数字来拼出相应的值,如果填入的数字是在两个X外面的,判断能否用除了这个数字以外的数字拼出相应的值,同时如果当前两个X外的值相加(1+2+...+n)-相应两个X之间的值,那么是非法。这道题补得可以说是非常难受了,好多细节出了问题,改了好久bug。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> #include<bitset> #include<unordered_map> const int maxn = 0x3f3f3f3f; const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427; const double PI = 3.141592653589793238462643383279; //#ifdef TRUETRUE //#define gets gets_s //#endif using namespace std; int n; int c[3][10]; int ans[11][11]; int ma[11] = { 6,10,15 }; unordered_map<int, int>mp1[11][22], mp2[11], mmp; struct s { int nn, num[66], c[66][66]; }z[11][22]; inline void init(void) { int i, j, zz, sum, tmp[20], tt, l; for (i = 5; i <= 7; i++) { for (j = 0; j <= 15; j++) { z[i][j].nn = 0; } } for (i = 5; i <= 7; i++) { for (zz = 0; zz < (1 << (i - 2)); zz++) { sum = 0; tt = 0; for (j = 1; j <= i - 2; j++) { if ((zz & (1 << (j - 1)))) { sum += j; tmp[tt++] = j; } } for (j = 0; j < tt; j++) { z[i][sum].c[z[i][sum].nn][j] = tmp[j]; } z[i][sum].num[z[i][sum].nn] = tt; z[i][sum].nn++; } } unordered_map<int, int>mp3; unordered_map<int, int>mp4; for (i = 5; i <= 7; i++) { for (j = 0; j <= ma[i - 5]; j++) { mp3.clear(); for (int zzz = 0; zzz < z[i][j].nn; zzz++) { //printf("*%d %d\n", z[i][j].num[zzz], j); for (int k = 0; k < z[i][j].num[zzz]; k++) { if (zzz == 0) { mp3[z[i][j].c[zzz][k]] = 1; } else { if (mp3[z[i][j].c[zzz][k]]) { mp4[z[i][j].c[zzz][k]] = 1; } } //printf("%d ", z[i][j].c[zzz][k]); } if (zzz) { mp3 = mp4; } mp4.clear(); //printf("\n"); } mp1[i][j] = mp3; /*printf("- "); for (int rrr = 0;rrr <= 15;rrr++) { if (mp1[i][j][rrr]) { printf("%d ",rrr); } } printf("\n"); printf("\n");*/ } //printf("************************************************\n"); } } inline bool checkx(int x, int y) { int i, sum = 0; int mmpt[20]; memset(mmpt, 0, sizeof(mmpt)); for (i = x; i >= 1; i--) { if (ans[i][y] == -1) { mmpt[17]++; } else { mmpt[ans[i][y]]++; } if (ans[i][y] == -1 && mmpt[17] >= 3 || ans[i][y] != -1 && mmpt[ans[i][y]] >= 2) { return false; } if (i <= x - 1) { if (ans[i][y] > 0) { sum += ans[i][y]; } else { if (sum != c[1][y]) { return false; } return true; } } } if (sum > ma[n - 5] - c[1][y]) { return false; } return true; } inline bool checknum(int x, int y) { int i, sum = 0, tmp = 0, sum2 = 0, flag3, j; int mmpt[20]; memset(mmpt, 0, sizeof(mmpt)); for (i = x; i >= 1; i--) { if (ans[i][y] == -1) { mmpt[17]++; } else { mmpt[ans[i][y]]++; } if (ans[i][y] == -1 && mmpt[17] >= 3 || ans[i][y] != -1 && mmpt[ans[i][y]] >= 2) { return false; } if (ans[i][y] == -1) { tmp++; } } memset(mmpt, 0, sizeof(mmpt)); /*for (i = 1; i <= y; i++) { if (ans[x][i] > 0) { mmpt[ans[x][i]]++; } if (ans[x][i] > 0 && mmpt[ans[x][i]] >= 2) { return false; } }*/ if (tmp == 0) { if (mp1[n][c[1][y]][ans[x][y]] != 0) { return false; } int mmmp[20]; memset(mmmp, 0, sizeof(mmmp)); for (i = 1; i <= x; i++) { if (ans[i][y] > 0) { mmmp[ans[i][y]] = 1; } } int flag10; for (i = 0; i < z[n][c[1][y]].nn; i++) { flag10 = 1; for (j = 0; j < z[n][c[1][y]].num[i]; j++) { if (mmmp[z[n][c[1][y]].c[i][j]]) { flag10 = 0; break; } } if (flag10) { break; } } if (flag10 == 0) { return false; } } else if (tmp == 1) { int mmmp[20]; memset(mmmp, 0, sizeof(mmmp)); int biaoji[20]; for (i = x; i >= 1; i--) { if (ans[i][y] == -1) { break; } mmmp[ans[i][y]] = 1; } int flag10; for (i = 0; i < z[n][c[1][y]].nn; i++) { memset(biaoji, 0, sizeof(biaoji)); flag10 = 1; for (j = 0; j < z[n][c[1][y]].num[i]; j++) { biaoji[z[n][c[1][y]].c[i][j]] = 1; } for (j = 0; j <= 15; j++) { if (!(mmmp[j] && biaoji[j] || !mmmp[j])) { flag10 = 0; break; } } if (flag10) { break; } } if (flag10 == 0) { return false; } } flag3 = 1; for (i = x; i >= 1; i--) { if (ans[i][y] != -1) { if (flag3) { sum += ans[i][y]; } } else { if (tmp == 1 && sum > c[1][y]) { return false; } else if (tmp == 1) { return true; } else if (tmp == 2) { if (flag3) { flag3 = 0; sum2 = sum; sum = 0; } else { flag3 = 1; } } } } if (sum + sum2 > ma[n - 5] - c[1][y]) { return false; } return true; } int qq[10][20]; int sss; inline void dfs(int x, bool flag, int pos) { /*for (int i = 1; i <= n && 1; i++) { for (int j = 1; j <= n; j++) { printf("%d ", ans[i][j]); } printf("\n"); }*/ if (x > n) { sss = 1; return; } int i, j, l; int ss = 0; for (i = 1; i <= n; i++) { if (ans[x][i] == 0) { ss++; } } if (ss == 0 && !sss) { dfs(x + 1, false, 1); if (sss) { return; } } if (!flag) { for (l = 0; l < z[n][c[0][x]].nn && !sss; l++) { for (i = 1; i + z[n][c[0][x]].num[l] + 1 <= n && !sss; i++) { ans[x][i] = -1; ans[x][i + z[n][c[0][x]].num[l] + 1] = -1; if (checkx(x, i) && checkx(x, i + z[n][c[0][x]].num[l] + 1) && !sss) { if (z[n][c[0][x]].num[l] == 0) { memset(qq[x], 0, sizeof(qq[x])); dfs(x, true, 1); memset(qq[x], 0, sizeof(qq[x])); if (sss) { return; } } else { sort(z[n][c[0][x]].c[l], z[n][c[0][x]].c[l] + z[n][c[0][x]].num[l]); memset(qq[x], 0, sizeof(qq[x])); for (int yyy = 0;yyy < z[n][c[0][x]].num[l];yyy++) { qq[x][z[n][c[0][x]].c[l][yyy]] = 1; } int ssss = 0; do { ssss++; int qw[66]; memcpy(qw, z[n][c[0][x]].c[l], sizeof(int) * z[n][c[0][x]].num[l]); bool flag2 = true; for (j = 0; j < z[n][c[0][x]].num[l]; j++) { ans[x][i + j + 1] = z[n][c[0][x]].c[l][j]; if (!checknum(x, i + j + 1)) { flag2 = false; break; } } if (flag2) { dfs(x, true, 1); if (sss) { return; } } memcpy(z[n][c[0][x]].c[l], qw, sizeof(int) * z[n][c[0][x]].num[l]); } while (next_permutation(z[n][c[0][x]].c[l], z[n][c[0][x]].c[l] + z[n][c[0][x]].num[l])); memset(qq[x], 0, sizeof(qq[x])); } } for (j = 1; j <= n; j++) { ans[x][j] = 0; } } } } else { for (i = pos; i <= n && !sss; i++) { if (ans[x][i] == 0) { //printf("qq = %d\n",qq[4]); for (j = 1; j <= n - 2 && !sss; j++) { if (qq[x][j]) { continue; } ans[x][i] = j; qq[x][j] = 1; if (checknum(x, i)) { dfs(x, true, i + 1); qq[x][j] = 0; if (sss) { return; } } qq[x][j] = 0; ans[x][i] = 0; } break; } } } } int main(void) { //ios::sync_with_stdio(false); init(); int T, i, j; scanf("%d", &T); while (T--) { scanf("%d", &n); memset(ans, 0, sizeof(ans)); for (i = 1; i <= n; i++) { scanf("%d", &c[0][i]); } for (i = 1; i <= n; i++) { scanf("%d", &c[1][i]); } sss = 0; dfs(1, false, 1); for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { if (ans[i][j] == -1) { printf("X"); } else { printf("%d", ans[i][j]); } /*if (j != n) { printf(" "); }*/ } printf("\n"); } if (T) { printf("\n"); } } return 0; }
Code:kk
Thinking:pai爷 kk
状压dp
f[ i ] [ s ] [ j ] +=f[ i-1 ] [ s' ][ k ]
表示第 i 个位置,状态为s(二进制),第i个位置填j的状态,然后就从题目给出的限制条件进行转移,看代码即可理解。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const ll p=1e9+7; ll f[18][(1<<15)+10][18]; int n; char op[20]; int main(){ while(cin>>n){ scanf("%s",op+1); CLR(f,0); for(int i=1;i<=n;i++) { f[1][1<<(i-1)][i]=1; } int tmp=0,tot=0; for(int i=2;i<=n;i++) { for(int j=1;j<=n;j++) { for(int s=0;s<(1<<n);s++) { tmp=s;//判断数字个数 合法 tot=0; while(tmp>0){ tot+=tmp%2; tmp>>=1; } if(tot!=i)continue; if(( s&(1<<(j-1)) )==0)continue;//没有了 j for(int k=1;k<=n;k++) { if(k==j)continue; if((1<<(k-1))&s==0)continue;//没有k if(op[i-1]=='0'){ if((j/k!=2||j%k!=0) && (k/j!=2||k%j!=0) ){ f[i][s][j]+=f[i-1][s^(1<<(j-1))][k]%p; f[i][s][j]%=p; } }else{ if((j/k==2&&j%k==0 )|| (k/j==2&&k%j==0)){ f[i][s][j]+=f[i-1][s^(1<<(j-1))][k]%p; f[i][s][j]%=p; } } } } } } ll ans=0; // printf("debug:%d\n",(1<<n)-1); for(int j=1;j<=n;j++) { ans=(ans+f[n][(1<<n)-1][j]%p)%p; } printf("%lld\n",ans); } }
Code: kk
Thinking :pai爷 kk
添加边,其实就是连成了一棵树,就是!一!棵!树!没有其他的有的没的,树形dfs一下,记录一下每个节点的儿子树,父边被走过的总数量就是 son[ i ]* (n-son[ i ])
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1e6+10; int head[maxn],tot; struct edge{ int to,Next; }a[maxn<<2]; ll son[maxn]; int n,m,x,y,u,v; ll zo; ll ans=0; const ll p=1e9+7; void init(){ CLR(son,0); CLR(head,-1); tot=0; ans=0; } void addv(int u,int v){ a[++tot].to=v; a[tot].Next=head[u]; head[u]=tot; } void dfs(int u,int fa){ son[u]=1; for(int i=head[u];i!=-1;i=a[i].Next) { int v=a[i].to; if(v==fa)continue; dfs(v,u); son[u]+=son[v]; } if(fa!=-1){ ans=(ans+son[u]*(zo-son[u])%p)%p; } } int main(){ while(cin>>n>>m) { init(); zo=((ll)n*m); for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); addv(u,v); addv(v,u); for(int j=2;j<=m;j++) { addv((j-1)*n+u,(j-1)*n+v); addv((j-1)*n+v,(j-1)*n+u); } } m--; while(m--) { scanf("%d%d%d%d",&x,&y,&u,&v); addv((x-1)*n+u,(y-1)*n+v); addv((y-1)*n+v,(x-1)*n+u); } dfs(1,-1); printf("%lld\n",ans); } }
补题:kk
听了杜教讲的做法,好巧妙。
对于题目中所说的两种改变区间的操作,有一个性质就是,对于所有大于x的数字,不管怎么变换,这些数字的相对位子都不变,小于等于x的数字也是这样。所以我们把大于x的数字变成1,小于等于x的数字变成0,在变化之前,先处理出每种数字的前缀和,然后用线段树来维护01序列。对于第2种操作,其实就是把 [ l , r ]的所有的0移到左边,1移到右边,这个用线段树就很好操作,第3种操作也是这样。
而对于第一种操作,我们就是要处理出 所有 0和1 在原序列中的值,这个就可以用之前处理的前缀和来完成。
三种操作都有一点点小的细节要考虑。
dls niub!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn=200010; const int inf=0x3f3f3f3f; ll a[maxn]; struct node{ ll sum,lazy; }tr[maxn<<2]; int n,q,pa,pb; ll x,prea[maxn],preb[maxn]; void init(){ pa=0,pb=0; } void build(int o,int l,int r){ if(l==r){ tr[o].sum=a[l]; tr[o].lazy=-1; return ; } int mid=(l+r)>>1; build(o<<1,l,mid); build((o<<1)|1,mid+1,r); tr[o].sum=tr[o<<1].sum+tr[(o<<1)|1].sum; tr[o].lazy=-1; } void pushup(int o){ tr[o].sum=tr[o<<1].sum+tr[o<<1|1].sum; } void pushdown(int o,int l,int r){ if(tr[o].lazy!=-1){ tr[o<<1].lazy=tr[o].lazy; tr[o<<1|1].lazy=tr[o].lazy; int mid=(l+r)>>1; tr[o<<1].sum=tr[o].lazy*(mid-l+1); tr[o<<1|1].sum=tr[o].lazy*(r-mid); tr[o].lazy=-1; } } void update(int o,int l,int r,int ql,int qr,ll val){ if(ql<=l&&r<=qr){ tr[o].lazy=val; tr[o].sum=val*(r-l+1); return; } pushdown(o,l,r); int mid=l+((r-l)>>1); if(ql<=mid)update(o<<1,l,mid,ql,qr,val); if(qr>=mid+1)update(o<<1|1,mid+1,r,ql,qr,val); pushup(o); } ll query(int o,int l,int r,int ql,int qr){ if(ql<=l&&qr>=r)return tr[o].sum; pushdown(o,l,r); int mid=(l+r)>>1; ll ans=0; if(ql<=mid)ans=query(o<<1,l,mid,ql,qr); if(qr>=mid+1)ans+=query(o<<1|1,mid+1,r,ql,qr); return ans; } int op,u,v; int main(){ while(cin>>n>>q>>x){ init(); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); if(a[i]<=x){ prea[++pa]=a[i]; prea[pa]+=prea[pa-1]; a[i]=0; }else{ preb[++pb]=a[i]; preb[pb]+=preb[pb-1]; a[i]=1; } } build(1,1,n); while(q--) { scanf("%d%d%d",&op,&u,&v); if(op==2){ ll tep=query(1,1,n,u,v); tep=v-u+1-tep; if(tep>0) update(1,1,n,u,u+tep-1,0); if(tep<v-u+1) update(1,1,n,u+tep,v,1); }else if(op==1){ if(u==1){ ll tp=query(1,1,n,u,v); ll ans=preb[tp]; ans+=prea[v-tp]; printf("%lld\n",ans); continue; } ll tp1=query(1,1,n,1,u-1); ll tp2=query(1,1,n,1,v); ll ans=preb[tp2]-preb[tp1]; tp1=u-1-tp1,tp2=v-tp2; ans+=prea[tp2]-prea[tp1]; printf("%lld\n",ans); }else{ ll tep=query(1,1,n,u,v); if(tep>0) update(1,1,n,u,u+tep-1,1); if(tep<v-u+1) update(1,1,n,u+tep,v,0); } } } }
Code:zz
Thinking:zz
题意:给出一张图,求图中相交的线段的对数。
m只有2000,直接m*m暴力判断就好了,本来以为套个板子就能ac,结果有很多小细节没考虑就wa了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define CLR(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; const int maxn = 0x3f3f3f3f; using namespace std; struct Point { long long x; long long y; }; typedef struct Point point; long long multi(point p0, point p1, point p2) { //return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y); if((p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y) > 0) { return 1; } if((p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y) < 0) { return -1; } return 0; } bool isIntersected(point s1, point e1, point s2, point e2) { return (max(s1.x, e1.x) >= min(s2.x, e2.x)) && (max(s2.x, e2.x) >= min(s1.x, e1.x)) && (max(s1.y, e1.y) >= min(s2.y, e2.y)) && (max(s2.y, e2.y) >= min(s1.y, e1.y)) && (multi(s1, s2, e1)*multi(s1, e1, e2)>=0) && (multi(s2, s1, e2)*multi(s2, e2, e1)>=0); } struct s { int a,b; }z[2020]; int main(void) { int n,m,i,j,ans; while(~scanf("%d %d",&n,&m)) { point po[2020]; for(i = 0;i < m;i++) { scanf("%d %d",&z[i].a,&z[i].b); } for(i = 1;i <= n;i++) { scanf("%lld %lld",&po[i].x,&po[i].y); } ans = 0; for(i = 0;i < m;i++) { for(j = i + 1;j < m;j++) { if(po[z[i].a].x == po[z[j].a].x && po[z[i].a].y == po[z[j].a].y || po[z[i].a].x == po[z[j].b].x && po[z[i].a].y == po[z[j].b].y || po[z[i].b].x == po[z[j].a].x && po[z[i].b].y == po[z[j].a].y || po[z[i].b].x == po[z[j].b].x && po[z[i].b].y == po[z[j].b].y) { if((po[z[i].a].x - po[z[i].b].x) * (po[z[j].a].y - po[z[j].b].y) == (po[z[i].a].y - po[z[i].b].y) * (po[z[j].a].x - po[z[j].b].x)) { if((po[z[i].a].x == po[z[j].a].x && po[z[i].a].y == po[z[j].a].y && (po[z[i].b].x - po[z[i].a].x) * (po[z[j].b].x - po[z[i].a].x) >= 0 || po[z[i].a].x == po[z[j].b].x && po[z[i].a].y == po[z[j].b].y && (po[z[i].b].x - po[z[i].a].x) * (po[z[j].a].x - po[z[i].a].x) >= 0 || po[z[i].b].x == po[z[j].a].x && po[z[i].b].y == po[z[j].a].y && (po[z[i].a].x - po[z[i].b].x) * (po[z[j].b].x - po[z[i].b].x) >= 0 ||po[z[i].b].x == po[z[j].b].x && po[z[i].b].y == po[z[j].b].y && (po[z[i].a].x - po[z[i].b].x) * (po[z[j].a].x - po[z[i].b].x) >= 0) && (po[z[i].a].y == po[z[i].b].y)) { ans++; } else if((po[z[i].a].x == po[z[j].a].x && po[z[i].a].y == po[z[j].a].y && (po[z[i].b].y - po[z[i].a].y) * (po[z[j].b].y - po[z[i].a].y) >= 0 || po[z[i].a].x == po[z[j].b].x && po[z[i].a].y == po[z[j].b].y && (po[z[i].b].y - po[z[i].a].y) * (po[z[j].a].y - po[z[i].a].y) >= 0 || po[z[i].b].x == po[z[j].a].x && po[z[i].b].y == po[z[j].a].y && (po[z[i].a].y - po[z[i].b].y) * (po[z[j].b].y - po[z[i].b].y) >= 0 ||po[z[i].b].x == po[z[j].b].x && po[z[i].b].y == po[z[j].b].y && (po[z[i].a].y - po[z[i].b].y) * (po[z[j].a].y - po[z[i].b].y) >= 0) && (po[z[i].a].x == po[z[i].b].x)) { ans++; } else if((po[z[i].a].x == po[z[j].a].x && po[z[i].a].y == po[z[j].a].y && (po[z[i].b].y - po[z[i].a].y) * (po[z[j].b].y - po[z[i].a].y) >= 0 || po[z[i].a].x == po[z[j].b].x && po[z[i].a].y == po[z[j].b].y && (po[z[i].b].y - po[z[i].a].y) * (po[z[j].a].y - po[z[i].a].y) >= 0 || po[z[i].b].x == po[z[j].a].x && po[z[i].b].y == po[z[j].a].y && (po[z[i].a].y - po[z[i].b].y) * (po[z[j].b].y - po[z[i].b].y) >= 0 ||po[z[i].b].x == po[z[j].b].x && po[z[i].b].y == po[z[j].b].y && (po[z[i].a].y - po[z[i].b].y) * (po[z[j].a].y - po[z[i].b].y) >= 0)) { ans++; } } continue; } bool flag = isIntersected(po[z[i].a],po[z[i].b],po[z[j].a],po[z[j].b]); if(flag) { //printf("%d %d %d %d\n",z[i].a,z[i].b,z[j].a,z[j].b); ans++; } } } printf("%d\n",ans); } return 0; }
赛后总结:
kk:今天开局以为几何题是板子题,眉头一皱发现事情并不简单,就看h题去了,结果智障的没有思路,pai爷一点拨就想通了,后来f题也在和pai爷的合作下写完了,感觉今天状态有点迷吧,还好代码都是一发ac的,以后不要再在h题这种简单题上卡了,加油。
pai爷:今天浑水摸鱼,想尝试几道数列的题,奈何水平不够都咕了。
zz:今天上来就发现两道签到题,稍微想了一下就知道该怎么做了,然后想了h,傻了,居然没想出来,队友有了思路以后就给队友去写了,然后看了几何题,题目感觉题目简单的,套个板子改改就好了,虽然通过率感人,但还是再测了几个样例以后就交了,果然wa了,发现少考虑了好多情况,最后想了好久,wa了5发才过(这场比赛我们队一共就wa了5发,我菜爆了)。