2019 CCPC-Wannafly Winter Camp Day5(Div2, onsite)

solve 5/11

A Cactus Draw

Code:zz

Thinking :zz

题解待补

#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;
}
View Code

C Division

Code:zz

Thinking:zz

题解待补

#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;
}
View Code

D Doppelblock

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

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+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);
    }
}
View Code

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+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);
    }
}
View Code

I Sorting

线段树,待补,好巧妙的思想。

J Special Judge

Code:zz

Thinking:zz

题解待补

#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;
}
View Code

赛后总结:

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

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

zz:

猜你喜欢

转载自www.cnblogs.com/mountaink/p/10317607.html