zoukankan      html  css  js  c++  java
  • bzoj 1002: [FJOI2007]轮状病毒

    (color{#0066ff}{ 题目描述 })

    轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
    和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示

     N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示

    现给定n(N<=100),编程计算有多少个不同的n轮状病毒

    (color{#0066ff}{输入格式})

    第一行有1个正整数n

    (color{#0066ff}{输出格式})

    计算出的不同的n轮状病毒数输出

    (color{#0066ff}{输入样例})

    3
    

    (color{#0066ff}{输出样例})

    16
    

    (color{#0066ff}{数据范围与提示})

    none

    (color{#0066ff}{ 题解 })

    暴力(2^n)

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
        char ch; LL x = 0, f = 1;
        while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
        for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
        return x * f;
    }
    struct node {
        int x, y;
        node(int x = 0, int y = 0): x(x), y(y) {}
    }e[110000];
    int b[100000];
    int n, m, ans;
    int fa[1000010];
    int findset(int x) { return x == fa[x]? fa[x] : fa[x] = findset(fa[x]); }
    void getans(int num) {
        for(int i = 1; i <= n; i++) fa[i] = i;
        for(int i = 1; i <= num; i++) {
            int x = findset(e[b[i]].x);
            int y = findset(e[b[i]].y);
            if(x == y) return;
            fa[x] = y;
        }
        ans++;
    }
    
    void dfs(int dep, int num) {
        if(dep == m + 1) {
            if(num != n - 1) return;
            getans(num);
            return;
        }
        b[num + 1] = dep;
        dfs(dep + 1, num + 1);
        dfs(dep + 1, num);
    }
    int main() {
        n = in() + 1;
        for(int i = 2; i <= n; i++) e[++m] = node(1, i);
        for(int i = 2; i < n; i++) e[++m] = node(i, i + 1);
        if(n > 3) e[++m] = node(n, 2);
        dfs(1, 0);
        printf("%d", ans);
        return 0;
    }
    

    打表

    1, 5, 16, 45, 121, 320, 841, 2205, 5776, 15125, 39601, 103680, 271441 
    

    然后发现有很多完全平方数

    发现都在奇数项位置

    于是开方后得到

    1, 4, 11, 29, 76,199, 521
    

    通过下面的程序找到规律

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    int f[] = {1, 4, 11, 29, 76, 199, 521};
    bool judge(int i, int j, int v) {
    	for(int g = 3; g <= 6; g += 2)
    		if(i * f[g - 2] + j * f[g - 1] + v != f[g]) return false;
    	return true;
    }
    int main() {
    	for(int i = -10; i <= 10; i++)
    		for(int j = -10; j <= 10; j++)
    			for(int v = -10; v <= 10; v++) {
    				if(judge(i, j, v)) {
    					printf("%d * f[i - 2] + %d * f[i - 1] + %d
    " , i, j, v);
    				}
    			}
    	return 0;
    }
    

    发现规律 (f[i]=3*f[i-1]-f[i-2])

    讨论完奇数项,自然到了偶数项,发现都是5的倍数,除去5之后,居然跟奇数项的规律一毛一样

    还得写高精qwq

    Code

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    struct node {
    	int a[1050], len;
    	node(int x = 0) {
    		memset(a, 0, sizeof a);
    		if(!x) len = 1;
    		else len = 0;
    		while(x) {
    			a[++len] = x % 10;
    			x /= 10;
    		}
    	}
    	void jinwei() { while(len > 1 && a[len] == 0) len--; }
    	friend node operator + (const node &a, const node &b) {
    		node t(0);
    		t.len = std::max(a.len, b.len) + 3;
    		for(int i = 1; i <= t.len; i++) {
    			t.a[i] += a.a[i] + b.a[i];
    			t.a[i + 1] += t.a[i] / 10;
    			t.a[i] %= 10;
    		}
    		return t.jinwei(), t;
    	}
    	friend node operator - (const node &a, const node &b) {
    		node t = a;
    		for(int i = 1; i <= t.len; i++) {
    			t.a[i] -= b.a[i];
    			if(t.a[i] < 0) t.a[i] += 10, t.a[i + 1]--;
    		}
    		return t.jinwei(), t;
    	}
    	friend node operator * (const node &a, const node &b) {
    		node t(0);
    		t.len = a.len + b.len + 2;
    		for(int i = 1; i <= a.len; i++)
    			for(int j = 1; j <= b.len; j++) {
    				t.a[i + j - 1] += a.a[i] * b.a[j];
    				t.a[i + j] += t.a[i + j - 1] / 10;
    				t.a[i + j - 1] %= 10;
    			}
    		return t.jinwei(), t;
    	}
    	void print() {
    		for(int i = len; i >= 1; i--) putchar(a[i] + '0');
    		puts("");
    	}
    }A[111];
    int main() {
    	int n = in();
    	node tre(3);
    	if(n & 1) {
    		A[1] = node(1);
    		A[3] = node(4);
    		for(int i = 5; i <= n; i += 2) A[i] = tre * A[i - 2] - A[i - 4];
    		(A[n] * A[n]).print();
    	}
    	else {
    		if(n == 2) printf("%d", 5);
    		else {
    			A[4] = node(3);
    			A[6] = node(8);i
    			for(int i = 8; i <= n; i += 2) A[i] = tre * A[i - 2] - A[i - 4];
    			(A[n] * A[n] * node(5)).print();
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    NET Core-TagHelper实现分页标签
    NET Core-学习笔记(三)
    NET Core-学习笔记(二)
    NET Core-学习笔记(一)
    MVC默认路由实现分页-PagerExtend.dll
    Tomcat优化
    JVM参数配置大全
    tomcat8+memcached session共享
    Tomcat+Nginx+Redis+MySQL实现反向代理、负载均衡、session共享
    搭建Tomcat应用服务器、tomcat虚拟主机及Tomcat多实例部署
  • 原文地址:https://www.cnblogs.com/olinr/p/10351239.html
Copyright © 2011-2022 走看看