2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何

2016 CCPC 网络赛

A - A water problem 水题,但读题有个坑,输入数字长度很大。。

B - Zhu and 772002

题意:给出n个数(给出的每个数的质因子最大不超过2000),选出多个数相乘得b。问有多少种选法让b 为完全平方数。

tags:高斯消元,求异或方程组解的个数。   好题

每个数先素数分解开。  对于2000以内的每个素数p[i],这n个数有奇数个p[i]则系数为1,偶数个则系数为0,最后n个数的p[i]系数异或和都要为0才会使得最后的积为完全平方数。    所以,构建出系数矩阵,然后高斯消元,解出异或方程组的秩rank,自由变元的数量即为 x=n-rank,最后解的个数为2^x,但要注意减去全部为0的一种情况。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 2000, M=310, mod=1000000007;

int pri[N], cnt;   bool mark[N+1];
void sieve_prime()
{
    rep(i,2,N) {
        if(mark[i]==0) pri[++cnt]=i;
        for(int j=i*i; j<=N; j+=i) mark[j]=1;
    }
}

int fpow(ll a,int b){ll ans=1; for(;b;b>>=1,a=a*a%mod) if(b&1) ans=ans*a%mod; return (int)ans;}
int n, mat[M][M];
ll a[N];
int gauss_rank(int c[][M])    //高斯消元求异或方程组的秩
{
    int i=1, j=1;
    while(i<=cnt && j<=n) {
        int r=0;
        rep(k,i,cnt) if(mat[k][j]) { r=k; break; }
        if(r)
        {
            swap(mat[r], mat[i]);
            rep(k,i+1,cnt) if(mat[k][j]) {
                rep(h,i,n) mat[k][h]^=mat[i][h];
            }
            i++;
        }
        j++;
    }
    return i-1;
}
int solve()
{
    rep(j,1,n) {
        ll tmp=a[j];
        rep(i,1,cnt) {    //构建系数矩阵
            while(tmp%pri[i]==0) {
                tmp/=pri[i], mat[i][j]^=1;
            }
        }
    }
    int x=n-gauss_rank(mat);     //自由变元数量
    return (fpow(2,x)-1+mod)%mod;
}
int main()
{
    sieve_prime();
    int T;   scanf("%d", &T);
    rep(cas,1,T) {
        mes(mat, 0);
        scanf("%d", &n);
        rep(i,1,n) scanf("%lld", &a[i]);
        printf("Case #%d:\n%d\n", cas, solve());
    }

    return 0;
}

C - Magic boy Bi Luo with his excited tree

题意:给出一棵树,在每个点有a[i]的财宝,但每条边有v[i]的花费,问从每个结点出发可得到的最大钱财数ans[i]。

tags:树形dp,好伤脑细胞的题。。码了好几发,莫名其妙的错,  待补

把每个结点分为往儿子不回来v1、往儿子回来v2、往父亲不回来fv1、往父亲回来fv2。第一次dfs维护出v1和v2,第二次dfs维护出fv1和fv2,最后答案就是max(v1+fv2, v2+fv1)。

D - Danganronpa

题意:n种礼物,每种有a[i]个。无穷多个学生的桌子排成一行,限制:1、每张桌子里要有一个神秘礼物和一个普通礼物;2、相邻的桌子里的普通礼物要不同;3、礼物要放在相邻的桌子里。    问最多有多少个学生拿到礼物。

tags:思维题,稍微理一下 maxn和sum/2 就好。

// D
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 200005;

int T, n, ai;
int main()
{
    scanf("%d", &T);
    rep(cas,1,T) {
        scanf("%d", &n);
        ll sum=0;
        int mx=0;
        rep(i,1,n) {
            scanf("%d", &ai);
            sum+=ai;
            mx=max(mx, ai);
        }
        ll ans;
        if(mx>sum/2) ans=min(((sum-mx)*2)+1, sum/2);
        else ans=sum/2;
        printf("Case #%d: %lld\n", cas, ans);
    } 

    return 0;
}

G - Mountain

题意: n*m的网格,每个网格有一个高度。定义周围网格高度都比其大的网格为山谷。给出了网格中的山谷位置,网格高度可以是1~n*m,但网格高度互不相同,求有多少种方案。

tags:bzoj 2669: [cqoi2012]局部极小值  原题

没搞懂,待补

// CCPC  G
const int maxn=1<<9, mod=772002;
char c[26][26];
int dp[26][maxn];    // dp[i][s]表示‘X‘的状态为s时,已经填数字填到了i的方案数
int a[8]={-1,-1,-1,0,1,1,1,0};
int b[8]={-1,0,1,1,1,0,-1,-1};
int n,m;
int id[26][26];    // id[i][j]表示第 i行 j列是第几个‘X‘,或者是 0则不是‘X‘
int cnt[maxn];
int nn[maxn];

int cal(int p){    //走过了 p个‘X‘
    int w=1<<p;
    for(int i=0;i<w;i++){
        cnt[i]=0;
        for(int j=0;j<n;j++){
            for(int f=0;f<m;f++){
                if(c[j][f]==‘.‘){    //
                    int flag=0;
                    for(int u=0;u<8;u++){
                        int x=j+a[u];
                        int y=f+b[u];
                        if(x>=0&&x<n&&y>=0&&y<m){
                            if(c[x][y]==‘X‘&&(i&(1<<id[x][y]))==0){
                                flag=1;    //不产生贡献
                                break;
                            }
                        }
                    }
                    cnt[i]+=flag^1;
                }
            }
        }
    }
    dp[0][0]=1;
    for(int i=1;i<=n*m;i++) {
        for(int j=0;j<w;j++) {
            dp[i][j]=((LL)dp[i-1][j]*(cnt[j]-(i-1-nn[j])))%mod;        //
            for(int q=0;q<p;q++) {
                if(j&(1<<q)) {
                    dp[i][j]+=dp[i-1][j^(1<<q)];    //
                    dp[i][j]%=mod;
                }
            }
        }
    }
    return dp[n*m][w-1];
}
int dfs(int x,int y,int p){    // 从(x,y)开始,有 t个‘.‘变为了‘X‘,走过了p个‘X‘
    if(x==n){
        if(t%2==0){
            return cal(p);
        }
        else return (mod-cal(p))%mod;
    }
    if(y==m) return dfs(x+1,0,p);    //换行
    if(c[x][y]==‘X‘){
        id[x][y]=p;
        return dfs(x,y+1,p+1); //遍历过一个‘X‘,p加一
    }
    int flag=0;
    for(int i=0;i<8;i++){
        int x1=x+a[i];
        int y1=y+b[i];
        if(x1>=0&&x1<n&&y1>=0&&y1<m&&c[x1][y1]==‘X‘){
            flag=1;
        }
    }
    int ans=dfs(x,y+1,p);
    if(flag==0){
        id[x][y]=p;
        c[x][y]=‘X‘;    //把‘.‘变为‘X‘
        ans+=dfs(x,y+1,p+1);    // +=
        ans%=mod;
        c[x][y]=‘.‘;    //再变回
        id[x][y]=0;
    }
    return ans;
}
int main()
{
    int N=0;
    for(int i=1;i<maxn;i++) nn[i]=nn[i&(i-1)]+1;
    while (scanf("%d%d",&n,&m)!=EOF) {
        for(int i=0;i<n;i++) scanf("%s",c[i]);
        int flag=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(c[i][j]==‘X‘){
                    for(int f=0;f<8;f++){
                        int x=i+a[f];
                        int y=j+b[f];
                        if(x>=0&&x<n&&y>=0&&y<m){
                            if(c[x][y]==‘X‘){
                                flag=1;
                            }
                        }
                    }
                }
            }
        }
        printf("Case #%d: ",++N);
        if(flag) printf("0\n");
        else{
            printf("%d\n",dfs(0,0,0));
        }
    }
}

H - Special Tetrahedron

题意:三维空间给出n 个点。定义特殊四面体:1、至少有4条相同长度的边;2、如果恰好有4条相同长度的边,另两条边要不相邻。 问有多少个特殊四面体。

tags:看了大神题解码的,转送门

思路:可以看成是求空间四边形,暴力枚举对角线。 对于每一条对角线,再枚举,把到两端点距离相等的点加到集合里。然后再枚举,看集合里任意两个点是否与两个端点共面。    最后去重,正四面体算了6次,两条边不等的算了2次。  时间复杂度O(n^4),但实际上,两个点与对角线两端点共面的情况只能在对角线中垂线上,不可能每次都有很多点在中垂线上,所以均摊下来时间复杂度并不高。

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 210;

struct Point {
    double x, y, z;
    Point operator - (const Point &b) const {
        return Point{b.x-x, b.y-y, b.z-z};
    }
}p[N];
double dis(Point a, Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z));
}
Point xmul(Point a, Point b) {    //叉积
    return Point{a.y*b.z-b.y*a.z, a.z*b.x-b.z*a.x, a.x*b.y-b.x*a.y};
}
double dmul(Point a, Point b) {    //返回 0则两向量垂直
    return a.x*b.x+a.y*b.y+a.z*b.z;
}
bool isgm(Point a, Point b, Point c, Point d) {    //返回 0则四点花线
    if(dmul(xmul(a-b,a-c), a-d)) return false;
    return true;
}

int n;
vector<Point > ve;
int solve()
{
    int ans1=0, ans2=0;
    rep(ca,1,n) rep(cb,ca+1,n) if(ca!=cb) {    //枚举对角线
        ve.clear();
        rep(i,1,n) if(i!=ca && i!=cb) {
            if(dis(p[i],p[ca])==dis(p[i],p[cb])) ve.push_back(p[i]);
        }
        int sz=ve.size();
        rep(i,0,sz-1) {
            double dis1=dis(ve[i],p[ca]);
            rep(j,i+1,sz-1) if(dis(ve[j],p[ca])==dis1) {
                if(isgm(p[ca],p[cb],ve[i],ve[j]))  continue;
                if(dis(ve[i],ve[j])==dis1 && dis(p[ca],p[cb])==dis1) ans2++;
                else ans1++;
            }
        }
    }
    ans1/=2, ans1=ans1+ans2/6;
    return ans1;
}
int main()
{
    int T;  scanf("%d", &T);
    rep(cas,1,T) {
        scanf("%d", &n);
        rep(i,1,n) scanf("%lf %lf %lf", &p[i].x, &p[i].y, &p[i].z);
        printf("Case #%d: %d\n", cas, solve());
    }

    return 0;
}

K - Lweb and String

题意:一个字符串,它的字符集合里,求它能够形成的最长递增子序列长度。

tags: SB题     被坑了,看懂题意,感觉题目反常就多看几遍 ==

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
typedef long long ll;
const int N = 200005;

int vis[200];
string s;
int main()
{
    int T;
    scanf("%d", &T);
    rep(cas,1,T) {
        cin>>s;
        int len=s.size();
        mes(vis,0);
        rep(i,0,len-1) vis[s[i]]=1;
        int ans=0;
        rep(i,0,199) if(vis[i]) ans++;
        printf("Case #%d: %d\n", cas, ans);
    }

    return 0;
}

时间: 2024-10-05 12:23:25

2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何的相关文章

HDU4870_Rating_双号从零单排_高斯消元求期望

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 415 Special Judge Problem Description A little gir

2015南阳CCPC E - Ba Gua Zhen 高斯消元 xor最大

Ba Gua Zhen Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description During the Three-Kingdom period, there was a general named Xun Lu who belonged to Kingdom Wu. Once his troop were chasing Bei Liu, he was stuck in the Ba Gua Zhen from Liang Zhuge.

2017湘潭赛 A题 Determinant (高斯消元取模)

链接 http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1260 今年湘潭的A题 题意不难 大意是把n*(n+1)矩阵去掉某一列 求去掉那一列之后的对应的行列式的值 mod 1e9+7 思路1  : 先做一次高斯消元 得到一个阶梯矩阵  只有最后两列没有被消元 然后每去掉一列 拿出新的矩阵  做一次消元 1      a12   a13   a14 0       1      a23   a24 0        0  

2014鞍山网络预选赛1010(缩点+高斯消元)hdu5006

Resistance Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 280    Accepted Submission(s): 82 Problem Description Recently DRD got a number of wires. Some of the wires have the resistance 1 ohm

(高斯消元)HDU 5006 Resistance 2014 鞍山网赛

题目链接 题意:有一个电路,用0/1的电阻连接起来.给定两点,问之间的电阻为多少? 先回忆一下中学物理知识,若用并联串联去做,碰到复杂电路根本分析不清.这里用到基尔霍夫定理. 在任一瞬时,流向某一结点的电流之和恒等于由该结点流出的电流之和. 在任一瞬间,沿电路中的任一回路绕行一周,在该回路上电动势之和恒等于各电阻上的电压降之和. 那么我们对于图中的点(电阻为0的看作一个点,缩点)都可以列方程  ∑(Ua-Ub)/Rab =0 Rab都是1所以某条边的电流就等于电压差了. 为了方便求结果,我们设S

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to

【BZOJ3640】JC的小苹果 概率DP+高斯消元

[BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话说JC历经艰辛来到了城市B,但是由于他的疏忽DZY偷走了他的小苹果!没有小苹果怎么听歌!他发现邪恶的DZY把他的小苹果藏在了一个迷宫里.JC在经历了之前的战斗后他还剩下hp点血.开始JC在1号点,他的小苹果在N号点.DZY在一些点里放了怪兽.当JC每次遇到位置在i的怪兽时他会损失Ai点血.当JC的血小于等于0时他就会被自动弹出迷

CDOJ 1330 柱爷与远古法阵【高斯消元,卡精度】

柱爷与远古法阵 Time Limit: 125/125MS (Java/Others)     Memory Limit: 240000/240000KB (Java/Others) Submit Status 众所周知,柱爷的数学非常好,尤其擅长概率论! 某日柱爷在喵哈哈村散步,无意间踏入了远古法阵! 法阵很奇怪,是一个长度为NN的走廊,初始时柱爷在最左边,现在柱爷要到最右边去! 柱爷的行动方式如下: 每个回合柱爷会投一次骰子,根据骰子上的点数每个回合柱爷会投一次骰子,根据骰子上的点数X,柱爷