solve 5/11

补题:7/11

A Cactus Draw

Code:zz

Thinking :zz

题意:要在n*n的网格内画上一棵节点数为n树,使得没有边相交。

很好想的构造题,因为网格有n*n,足够大,所以结点1放在(1,1)的位置,与结点1相连的结点依次放在(2,1),(2,2)...的位子,依此类推。

#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[],ans[];
vector<int>ve[];
int c[],hi[],d[];
int main(void)
{
int n,m,i,si,j,pos,cnt;
while(~scanf("%d %d",&n,&m))
{
memset(c,,sizeof(c));
memset(d,,sizeof(d));
memset(hi,,sizeof(hi));
for(i = ;i <= n;i++)
{
ve[i].clear();
}
for(i = ;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();
cnt = ;
c[] = ;
d[] = ;
hi[] = ;
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 = ;j < si;j++)
{
//printf(" %d ",ve[pos][j]);
if(!c[ve[pos][j]])
{
c[ve[pos][j]] = c[pos] + ;
d[ve[pos][j]] = hi[c[ve[pos][j]]] + ;
hi[c[ve[pos][j]]]++;
q.push(ve[pos][j]);
}
}
//printf("\n");
}
for(i = ;i <= n;i++)
{
printf("%d %d\n",ans[i].a,ans[i].b);
}
}
return ;
}

C Division

Code:zz

Thinking:zz

k很大,有1e9,但是n只有1e5,ai只有1e9,所以最多经过1e5*log(1e9)就能使所有数字变为0。用一个优先队列来存放数字,每次取出最大的一个并/2,然后放回,等到取出的数字为0或者操作次数用尽,就退出,然后把优先队列里的值加起来就好了。

#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[];
int main(void)
{
int n, m, i;
long long ans, pos;
while (~scanf("%d %d", &n, &m))
{
priority_queue<long long>q;
for (i = ; i < n; i++)
{
scanf("%lld", c + i);
q.push(c[i]);
}
while (m > )
{
pos = q.top();
//printf("%d\n",pos);
q.pop();
if (pos == || m == )
{
break;
}
pos /= ;
q.push(pos);
m--;
}
ans = ;
while (!q.empty())
{
pos = q.top();
q.pop();
ans += pos;
}
printf("%lld\n", ans);
}
return ;
}

D Doppelblock

搜索,待补,比赛的时候kk和pai爷提出了两个能ac的想法,但踏马的就是没写。

补题:zz

这是一道搜索题,可以先根据n和两个X之间的值的和枚举两个X的位置,再枚举两个X之间的数字可能的组合,可以通过预处理先把n=5,6,7时的所有和的情况全部处理出来,可以用二进制枚举达到这一点;其次,我还考虑了好多剪枝,在填上数字或者X的时候,判断行列是否有重复元素,如果填入的数字是在两个X之间的,判断能否用当前已有的两个X之间的数字来拼出相应的值,如果填入的数字是在两个X外面的,判断能否用除了这个数字以外的数字拼出相应的值,同时如果当前两个X外的值相加(1+2+...+n)-相应两个X之间的值,那么是非法。这道题补得可以说是非常难受了,好多细节出了问题,改了好久bug。

//#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[][];
int ans[][];
int ma[] = { ,, };
unordered_map<int, int>mp1[][], mp2[], mmp;
struct s
{
int nn, num[], c[][];
}z[][];
inline void init(void)
{
int i, j, zz, sum, tmp[], tt, l;
for (i = ; i <= ; i++)
{
for (j = ; j <= ; j++)
{
z[i][j].nn = ;
}
}
for (i = ; i <= ; i++)
{
for (zz = ; zz < ( << (i - )); zz++)
{
sum = ;
tt = ;
for (j = ; j <= i - ; j++)
{
if ((zz & ( << (j - ))))
{
sum += j;
tmp[tt++] = j;
}
}
for (j = ; 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 = ; i <= ; i++)
{
for (j = ; j <= ma[i - ]; j++)
{
mp3.clear();
for (int zzz = ; zzz < z[i][j].nn; zzz++)
{
//printf("*%d %d\n", z[i][j].num[zzz], j);
for (int k = ; k < z[i][j].num[zzz]; k++)
{
if (zzz == )
{
mp3[z[i][j].c[zzz][k]] = ;
}
else
{
if (mp3[z[i][j].c[zzz][k]])
{
mp4[z[i][j].c[zzz][k]] = ;
}
}
//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 = ;
int mmpt[];
memset(mmpt, , sizeof(mmpt));
for (i = x; i >= ; i--)
{
if (ans[i][y] == -)
{
mmpt[]++;
}
else
{
mmpt[ans[i][y]]++;
}
if (ans[i][y] == - && mmpt[] >= || ans[i][y] != - && mmpt[ans[i][y]] >= )
{
return false;
}
if (i <= x - )
{
if (ans[i][y] > )
{
sum += ans[i][y];
}
else
{
if (sum != c[][y])
{
return false;
}
return true;
}
}
}
if (sum > ma[n - ] - c[][y])
{
return false;
}
return true;
}
inline bool checknum(int x, int y)
{
int i, sum = , tmp = , sum2 = , flag3, j;
int mmpt[];
memset(mmpt, , sizeof(mmpt));
for (i = x; i >= ; i--)
{
if (ans[i][y] == -)
{
mmpt[]++;
}
else
{
mmpt[ans[i][y]]++;
}
if (ans[i][y] == - && mmpt[] >= || ans[i][y] != - && mmpt[ans[i][y]] >= )
{
return false;
}
if (ans[i][y] == -)
{
tmp++;
}
}
memset(mmpt, , 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 == )
{
if (mp1[n][c[][y]][ans[x][y]] != )
{
return false;
}
int mmmp[];
memset(mmmp, , sizeof(mmmp));
for (i = ; i <= x; i++)
{
if (ans[i][y] > )
{
mmmp[ans[i][y]] = ;
}
}
int flag10;
for (i = ; i < z[n][c[][y]].nn; i++)
{
flag10 = ;
for (j = ; j < z[n][c[][y]].num[i]; j++)
{
if (mmmp[z[n][c[][y]].c[i][j]])
{
flag10 = ;
break;
}
}
if (flag10)
{
break;
}
}
if (flag10 == )
{
return false;
}
}
else if (tmp == )
{
int mmmp[];
memset(mmmp, , sizeof(mmmp));
int biaoji[];
for (i = x; i >= ; i--)
{
if (ans[i][y] == -)
{
break;
}
mmmp[ans[i][y]] = ;
}
int flag10;
for (i = ; i < z[n][c[][y]].nn; i++)
{
memset(biaoji, , sizeof(biaoji));
flag10 = ;
for (j = ; j < z[n][c[][y]].num[i]; j++)
{
biaoji[z[n][c[][y]].c[i][j]] = ;
}
for (j = ; j <= ; j++)
{
if (!(mmmp[j] && biaoji[j] || !mmmp[j]))
{
flag10 = ;
break;
}
}
if (flag10)
{
break;
}
}
if (flag10 == )
{
return false;
}
}
flag3 = ;
for (i = x; i >= ; i--)
{
if (ans[i][y] != -)
{
if (flag3)
{
sum += ans[i][y];
}
}
else
{
if (tmp == && sum > c[][y])
{
return false;
}
else if (tmp == )
{
return true;
}
else if (tmp == )
{
if (flag3)
{
flag3 = ;
sum2 = sum;
sum = ;
}
else
{
flag3 = ;
}
}
}
}
if (sum + sum2 > ma[n - ] - c[][y])
{
return false;
}
return true;
} int qq[][];
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 = ;
return;
}
int i, j, l;
int ss = ;
for (i = ; i <= n; i++)
{
if (ans[x][i] == )
{
ss++;
}
}
if (ss == && !sss)
{
dfs(x + , false, );
if (sss)
{
return;
}
}
if (!flag)
{
for (l = ; l < z[n][c[][x]].nn && !sss; l++)
{
for (i = ; i + z[n][c[][x]].num[l] + <= n && !sss; i++)
{
ans[x][i] = -;
ans[x][i + z[n][c[][x]].num[l] + ] = -;
if (checkx(x, i) && checkx(x, i + z[n][c[][x]].num[l] + ) && !sss)
{
if (z[n][c[][x]].num[l] == )
{
memset(qq[x], , sizeof(qq[x]));
dfs(x, true, );
memset(qq[x], , sizeof(qq[x]));
if (sss)
{
return;
}
}
else
{
sort(z[n][c[][x]].c[l], z[n][c[][x]].c[l] + z[n][c[][x]].num[l]);
memset(qq[x], , sizeof(qq[x]));
for (int yyy = ;yyy < z[n][c[][x]].num[l];yyy++)
{
qq[x][z[n][c[][x]].c[l][yyy]] = ;
}
int ssss = ;
do
{
ssss++;
int qw[];
memcpy(qw, z[n][c[][x]].c[l], sizeof(int) * z[n][c[][x]].num[l]);
bool flag2 = true;
for (j = ; j < z[n][c[][x]].num[l]; j++)
{
ans[x][i + j + ] = z[n][c[][x]].c[l][j];
if (!checknum(x, i + j + ))
{
flag2 = false;
break;
}
}
if (flag2)
{
dfs(x, true, );
if (sss)
{
return;
}
}
memcpy(z[n][c[][x]].c[l], qw, sizeof(int) * z[n][c[][x]].num[l]);
} while (next_permutation(z[n][c[][x]].c[l],
z[n][c[][x]].c[l] + z[n][c[][x]].num[l]));
memset(qq[x], , sizeof(qq[x]));
}
}
for (j = ; j <= n; j++)
{
ans[x][j] = ;
}
}
}
}
else
{ for (i = pos; i <= n && !sss; i++)
{
if (ans[x][i] == )
{
//printf("qq = %d\n",qq[4]);
for (j = ; j <= n - && !sss; j++)
{
if (qq[x][j])
{
continue;
}
ans[x][i] = j;
qq[x][j] = ;
if (checknum(x, i))
{
dfs(x, true, i + );
qq[x][j] = ;
if (sss)
{
return;
}
}
qq[x][j] = ;
ans[x][i] = ;
}
break;
}
}
}
}
int main(void)
{
//ios::sync_with_stdio(false);
init();
int T, i, j;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
memset(ans, , sizeof(ans));
for (i = ; i <= n; i++)
{
scanf("%d", &c[][i]);
}
for (i = ; i <= n; i++)
{
scanf("%d", &c[][i]);
}
sss = ;
dfs(, false, );
for (i = ; i <= n; i++)
{
for (j = ; j <= n; j++)
{
if (ans[i][j] == -)
{
printf("X");
}
else
{
printf("%d", ans[i][j]);
}
/*if (j != n)
{
printf(" ");
}*/
}
printf("\n");
}
if (T)
{
printf("\n");
}
}
return ;
}

F Kropki

Code:kk

Thinking:pai爷  kk

状压dp

f[ i ] [ s ] [ j ] +=f[ i-1 ] [ s' ][ k ]

表示第 i 个位置,状态为s(二进制),第i个位置填j的状态,然后就从题目给出的限制条件进行转移,看代码即可理解。

#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const ll p=1e9+;
ll f[][(<<)+][];
int n;
char op[];
int main(){
while(cin>>n){
scanf("%s",op+);
CLR(f,);
for(int i=;i<=n;i++)
{
f[][<<(i-)][i]=;
}
int tmp=,tot=;
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
for(int s=;s<(<<n);s++)
{
tmp=s;//判断数字个数 合法
tot=;
while(tmp>){
tot+=tmp%;
tmp>>=;
}
if(tot!=i)continue; if(( s&(<<(j-)) )==)continue;//没有了 j
for(int k=;k<=n;k++)
{
if(k==j)continue;
if((<<(k-))&s==)continue;//没有k if(op[i-]==''){
if((j/k!=||j%k!=) && (k/j!=||k%j!=) ){
f[i][s][j]+=f[i-][s^(<<(j-))][k]%p;
f[i][s][j]%=p;
}
}else{
if((j/k==&&j%k== )|| (k/j==&&k%j==)){
f[i][s][j]+=f[i-][s^(<<(j-))][k]%p;
f[i][s][j]%=p;
}
}
}
}
}
}
ll ans=;
// printf("debug:%d\n",(1<<n)-1);
for(int j=;j<=n;j++)
{
ans=(ans+f[n][(<<n)-][j]%p)%p;
}
printf("%lld\n",ans);
}
}

H Nested Tree

Code: kk

Thinking :pai爷  kk

添加边,其实就是连成了一棵树,就是!一!棵!树!没有其他的有的没的,树形dfs一下,记录一下每个节点的儿子树,父边被走过的总数量就是 son[ i ]* (n-son[ i ])

#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=1e6+;
int head[maxn],tot;
struct edge{
int to,Next;
}a[maxn<<];
ll son[maxn];
int n,m,x,y,u,v;
ll zo;
ll ans=;
const ll p=1e9+;
void init(){
CLR(son,);
CLR(head,-);
tot=;
ans=;
}
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]=;
for(int i=head[u];i!=-;i=a[i].Next)
{
int v=a[i].to;
if(v==fa)continue;
dfs(v,u);
son[u]+=son[v];
}
if(fa!=-){
ans=(ans+son[u]*(zo-son[u])%p)%p;
}
}
int main(){
while(cin>>n>>m)
{
init();
zo=((ll)n*m);
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
addv(u,v);
addv(v,u);
for(int j=;j<=m;j++)
{
addv((j-)*n+u,(j-)*n+v);
addv((j-)*n+v,(j-)*n+u);
}
}
m--;
while(m--)
{
scanf("%d%d%d%d",&x,&y,&u,&v);
addv((x-)*n+u,(y-)*n+v);
addv((y-)*n+v,(x-)*n+u);
}
dfs(,-);
printf("%lld\n",ans);
}
}

I Sorting

补题:kk

听了杜教讲的做法,好巧妙。

对于题目中所说的两种改变区间的操作,有一个性质就是,对于所有大于x的数字,不管怎么变换,这些数字的相对位子都不变,小于等于x的数字也是这样。所以我们把大于x的数字变成1,小于等于x的数字变成0,在变化之前,先处理出每种数字的前缀和,然后用线段树来维护01序列。对于第2种操作,其实就是把 [ l , r ]的所有的0移到左边,1移到右边,这个用线段树就很好操作,第3种操作也是这样。

而对于第一种操作,我们就是要处理出 所有 0和1 在原序列中的值,这个就可以用之前处理的前缀和来完成。

三种操作都有一点点小的细节要考虑。

dls niub!

#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=;
const int inf=0x3f3f3f3f;
ll a[maxn];
struct node{
ll sum,lazy;
}tr[maxn<<];
int n,q,pa,pb;
ll x,prea[maxn],preb[maxn];
void init(){
pa=,pb=;
}
void build(int o,int l,int r){
if(l==r){
tr[o].sum=a[l];
tr[o].lazy=-;
return ;
}
int mid=(l+r)>>;
build(o<<,l,mid);
build((o<<)|,mid+,r);
tr[o].sum=tr[o<<].sum+tr[(o<<)|].sum;
tr[o].lazy=-;
}
void pushup(int o){
tr[o].sum=tr[o<<].sum+tr[o<<|].sum;
}
void pushdown(int o,int l,int r){
if(tr[o].lazy!=-){
tr[o<<].lazy=tr[o].lazy;
tr[o<<|].lazy=tr[o].lazy;
int mid=(l+r)>>;
tr[o<<].sum=tr[o].lazy*(mid-l+);
tr[o<<|].sum=tr[o].lazy*(r-mid);
tr[o].lazy=-;
}
}
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+);
return;
}
pushdown(o,l,r);
int mid=l+((r-l)>>);
if(ql<=mid)update(o<<,l,mid,ql,qr,val);
if(qr>=mid+)update(o<<|,mid+,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)>>;
ll ans=;
if(ql<=mid)ans=query(o<<,l,mid,ql,qr);
if(qr>=mid+)ans+=query(o<<|,mid+,r,ql,qr);
return ans;
}
int op,u,v;
int main(){
while(cin>>n>>q>>x){
init();
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
if(a[i]<=x){
prea[++pa]=a[i];
prea[pa]+=prea[pa-];
a[i]=;
}else{
preb[++pb]=a[i];
preb[pb]+=preb[pb-];
a[i]=;
}
}
build(,,n);
while(q--)
{
scanf("%d%d%d",&op,&u,&v);
if(op==){
ll tep=query(,,n,u,v);
tep=v-u+-tep;
if(tep>)
update(,,n,u,u+tep-,);
if(tep<v-u+)
update(,,n,u+tep,v,);
}else if(op==){
if(u==){
ll tp=query(,,n,u,v);
ll ans=preb[tp];
ans+=prea[v-tp];
printf("%lld\n",ans);
continue;
}
ll tp1=query(,,n,,u-);
ll tp2=query(,,n,,v);
ll ans=preb[tp2]-preb[tp1];
tp1=u--tp1,tp2=v-tp2;
ans+=prea[tp2]-prea[tp1];
printf("%lld\n",ans);
}else{
ll tep=query(,,n,u,v);
if(tep>)
update(,,n,u,u+tep-,);
if(tep<v-u+)
update(,,n,u+tep,v,);
}
}
}
}

J Special Judge

Code:zz

Thinking:zz

题意:给出一张图,求图中相交的线段的对数。

m只有2000,直接m*m暴力判断就好了,本来以为套个板子就能ac,结果有很多小细节没考虑就wa了。

#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) > )
{
return ;
}
if((p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y) < )
{
return -;
}
return ;
}
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)>=) && (multi(s2, s1, e2)*multi(s2, e2, e1)>=);
}
struct s
{
int a,b;
}z[];
int main(void)
{
int n,m,i,j,ans;
while(~scanf("%d %d",&n,&m))
{
point po[];
for(i = ;i < m;i++)
{
scanf("%d %d",&z[i].a,&z[i].b);
}
for(i = ;i <= n;i++)
{
scanf("%lld %lld",&po[i].x,&po[i].y);
}
ans = ;
for(i = ;i < m;i++)
{
for(j = i + ;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) >=
|| 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) >=
|| 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) >=
||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) >= )
&& (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) >=
|| 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) >=
|| 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) >=
||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) >= )
&& (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) >=
|| 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) >=
|| 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) >=
||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) >= ))
{
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 ;
}

赛后总结:

kk:今天开局以为几何题是板子题,眉头一皱发现事情并不简单,就看h题去了,结果智障的没有思路,pai爷一点拨就想通了,后来f题也在和pai爷的合作下写完了,感觉今天状态有点迷吧,还好代码都是一发ac的,以后不要再在h题这种简单题上卡了,加油。

pai爷:今天浑水摸鱼,想尝试几道数列的题,奈何水平不够都咕了。

zz:今天上来就发现两道签到题,稍微想了一下就知道该怎么做了,然后想了h,傻了,居然没想出来,队友有了思路以后就给队友去写了,然后看了几何题,题目感觉题目简单的,套个板子改改就好了,虽然通过率感人,但还是再测了几个样例以后就交了,果然wa了,发现少考虑了好多情况,最后想了好久,wa了5发才过(这场比赛我们队一共就wa了5发,我菜爆了)。

05-12 11:25