zoukankan      html  css  js  c++  java
  • 复(学)习化学时突然的一个 idea

    期中考试成功探底。。。但是某些化学问题还是很有信息学价值的。。。

    n 烷同分异构体计数。

    这个题 fanhq666 出过,就是一个 dp。

    设 f[i] 表示含有 i 个节点的无标号不同构的度数限制为 4 的有根树的个数。那么转移时枚举最多 3 个子树的大小,如果大小相同时用组合数,否则乘法原理就好了。

    最后统计答案时找到中心为根,然后最多 4 个子树,每个大小不超过 [n / 2] - 1(除法取上整),同样的累计方法(组合数/乘法原理)统计一下就好了;双重心时需要把两个重心同时提上去统计一遍和刚才的答案累加。

    没事闲的写了个比较全的高精度,先贴高精度模板。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    struct LL {
    	int len, A[510];
    	
    	LL() { len = -1; }
    	LL(int x) {
    		A[1] = x; len = 1;
    		if(x) while(A[len] > 9) A[len+1] = A[len] / 10, A[len] %= 10, len++;
    		else len = -1;
    	}
    	
    	LL operator = (const int& t) {
    		A[1] = t; len = 1;
    		if(t) while(A[len] > 9) A[len+1] = A[len] / 10, A[len] %= 10, len++;
    		else len = -1;
    		return *this;
    	}
    	
    	LL operator + (const LL& t) const {
    		LL ans; ans.len = max(len, t.len);
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = (i <= len ? A[i] : 0) + (i <= t.len ? t.A[i] : 0);
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] > 9) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
    		while(ans.A[ans.len] > 9) ans.A[ans.len+1] = ans.A[ans.len] / 10, ans.A[ans.len] %= 10, ans.len++;
    		return ans;
    	}
    	LL operator += (const LL& t) {
    		*this = *this + t;
    		return *this;
    	}
    	LL operator + (const int& t) const {
    		LL ans; ans.len = max(len, 1);
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = A[i]; ans.A[1] += t;
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] > 9) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
    		while(ans.A[ans.len] > 9) ans.A[ans.len+1] = ans.A[ans.len] / 10, ans.A[ans.len] %= 10, ans.len++;
    		return ans;
    	}
    	LL operator += (const int& t) {
    		*this = *this + t;
    		return *this;
    	}
    	LL operator ++ () { // ++this;
    		*this = *this + 1;
    		return *this;
    	}
    	LL operator ++ (int x) { // this++;
    		*this = *this + 1;
    		return *this - 1;
    	}
    	
    	LL operator - (const LL& t) const {
    		LL ans; ans.len = max(len, t.len);
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = A[i] - t.A[i];
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] < 0) {
    			int tmp = (-ans.A[i] + 9) / 10;
    			ans.A[i+1] -= tmp; ans.A[i] += tmp * 10;
    		}
    		while(!ans.A[ans.len]) ans.len--;
    		return ans;
    	}
    	LL operator -= (const LL& t) {
    		*this = *this - t;
    		return *this;
    	}
    	LL operator - (const int& t) const {
    		LL ans; ans.len = len;
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = A[i]; ans.A[1] -= t;
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] < 0) {
    			int tmp = (-ans.A[i] + 9) / 10;
    			ans.A[i+1] -= tmp; ans.A[i] += tmp * 10;
    		}
    		while(!ans.A[ans.len]) ans.len--;
    		return ans;
    	}
    	LL operator -= (const int& t) {
    		*this = *this - t;
    		return *this;
    	}
    	LL operator -- () { // --this;
    		*this = *this - 1;
    		return *this;
    	}
    	LL operator -- (int x) { // this--;
    		*this = *this - 1;
    		return *this + 1;
    	}
    	
    	LL operator * (const LL& t) const {
    		LL ans; ans.len = len + t.len - 1;
    		if(len < 0 || t.len < 0) return ans.len = -1, ans;
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = 0;
    		for(int i = 1; i <= len; i++)
    			for(int j = 1; j <= t.len; j++) ans.A[i+j-1] += A[i] * t.A[j];
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] > 9) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
    		while(ans.A[ans.len] > 9) ans.A[ans.len+1] = ans.A[ans.len] / 10, ans.A[ans.len] %= 10, ans.len++;
    		return ans;
    	}
    	LL operator *= (const LL& t) {
    		*this = *this * t;
    		return *this;
    	}
    	LL operator * (const int& t) const {
    		LL ans = t;
    		return ans * (*this);
    	}
    	LL operator *= (const int& t) {
    		*this = *this * t;
    		return *this;
    	}
    	
    	bool operator < (const LL& t) const {
    		if(len != t.len) return len < t.len;
    		for(int i = len; i > 0; i--) if(A[i] != t.A[i]) return A[i] < t.A[i];
    		return 0;
    	}
    	bool operator > (const LL& t) const {
    		if(len != t.len) return len > t.len;
    		for(int i = len; i > 0; i--) if(A[i] != t.A[i]) return A[i] > t.A[i];
    		return 0;
    	}
    	bool operator == (const LL& t) const {
    		if(len != t.len) return 0;
    		for(int i = len; i > 0; i--) if(A[i] != t.A[i]) return 0;
    		return 1;
    	}
    	bool operator != (const LL& t) const {
    		return !((*this) == t);
    	}
    	bool operator <= (const LL& t) const {
    		return *this < t || *this == t;
    	}
    	bool operator >= (const LL& t) const {
    		return *this > t || *this == t;
    	}
    	
    	LL operator / (const LL& t) const {
    		LL ans, f = 0; ans.len = -1;
    		for(int i = 1; i <= len; i++) ans.A[i] = 0;
    		for(int i = len; i > 0; i--) {
    			f = f * 10 + A[i];
    			while(f >= t) {
    				f -= t; ans.A[i]++;
    				ans.len = max(ans.len, i);
    			}
    		}
    		return ans;
    	}
    	LL operator /= (const LL& t) {
    		*this = *this / t;
    		return *this;
    	}
    	LL operator / (const int& t) const {
    		LL ans; int f = 0; ans.len = -1;
    		for(int i = 1; i <= len; i++) ans.A[i] = 0;
    		for(int i = len; i > 0; i--) {
    			f = f * 10 + A[i];
    			while(f >= t) {
    				f -= t; ans.A[i]++;
    				ans.len = max(ans.len, i);
    			}
    		}
    		return ans;
    	}
    	LL operator /= (const int& t) {
    		*this = *this / t;
    		return *this;
    	}
    	
    	void print() {
    		if(len < 0){ putchar('0'); return ; }
    		for(int i = len; i > 0; i--) putchar(A[i] + '0'); putchar('
    ');
    		return ;
    	}
    } A, B;
    
    int main() {
    	while(1) {
    		A = read(); B = read();
    		(A + B).print();
    		(A - B).print();
    		(A * B).print();
    		(A / B).print();
    		(A++).print();
    		(++A).print();
    		(B--).print();
    		(--B).print();
    	}
    	
    	return 0;
    }
    /*
    8997622 2333
    */
    

    再贴这道题的程序。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    #include <string>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 1010
    
    struct LL {
    	int len, A[510];
    	
    	LL() { len = -1; }
    	LL(int x) {
    		A[1] = x; len = 1;
    		if(x) while(A[len] > 9) A[len+1] = A[len] / 10, A[len] %= 10, len++;
    		else len = -1;
    	}
    	
    	LL operator = (const int& t) {
    		A[1] = t; len = 1;
    		if(t) while(A[len] > 9) A[len+1] = A[len] / 10, A[len] %= 10, len++;
    		else len = -1;
    		return *this;
    	}
    	
    	LL operator + (const LL& t) const {
    		LL ans; ans.len = max(len, t.len);
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = (i <= len ? A[i] : 0) + (i <= t.len ? t.A[i] : 0);
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] > 9) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
    		while(ans.A[ans.len] > 9) ans.A[ans.len+1] = ans.A[ans.len] / 10, ans.A[ans.len] %= 10, ans.len++;
    		return ans;
    	}
    	LL operator += (const LL& t) {
    		*this = *this + t;
    		return *this;
    	}
    	LL operator + (const int& t) const {
    		LL ans; ans.len = max(len, 1);
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = A[i]; ans.A[1] += t;
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] > 9) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
    		while(ans.A[ans.len] > 9) ans.A[ans.len+1] = ans.A[ans.len] / 10, ans.A[ans.len] %= 10, ans.len++;
    		return ans;
    	}
    	LL operator += (const int& t) {
    		*this = *this + t;
    		return *this;
    	}
    	LL operator ++ () { // ++this;
    		*this = *this + 1;
    		return *this;
    	}
    	LL operator ++ (int x) { // this++;
    		*this = *this + 1;
    		return *this - 1;
    	}
    	
    	LL operator - (const LL& t) const {
    		LL ans; ans.len = max(len, t.len);
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = A[i] - t.A[i];
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] < 0) {
    			int tmp = (-ans.A[i] + 9) / 10;
    			ans.A[i+1] -= tmp; ans.A[i] += tmp * 10;
    		}
    		while(!ans.A[ans.len]) ans.len--;
    		return ans;
    	}
    	LL operator -= (const LL& t) {
    		*this = *this - t;
    		return *this;
    	}
    	LL operator - (const int& t) const {
    		LL ans; ans.len = len;
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = A[i]; ans.A[1] -= t;
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] < 0) {
    			int tmp = (-ans.A[i] + 9) / 10;
    			ans.A[i+1] -= tmp; ans.A[i] += tmp * 10;
    		}
    		while(!ans.A[ans.len]) ans.len--;
    		return ans;
    	}
    	LL operator -= (const int& t) {
    		*this = *this - t;
    		return *this;
    	}
    	LL operator -- () { // --this;
    		*this = *this - 1;
    		return *this;
    	}
    	LL operator -- (int x) { // this--;
    		*this = *this - 1;
    		return *this + 1;
    	}
    	
    	LL operator * (const LL& t) const {
    		LL ans; ans.len = len + t.len - 1;
    		if(len < 0 || t.len < 0) return ans.len = -1, ans;
    		for(int i = 1; i <= ans.len; i++) ans.A[i] = 0;
    		for(int i = 1; i <= len; i++)
    			for(int j = 1; j <= t.len; j++) ans.A[i+j-1] += A[i] * t.A[j];
    		for(int i = 1; i < ans.len; i++) if(ans.A[i] > 9) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
    		while(ans.A[ans.len] > 9) ans.A[ans.len+1] = ans.A[ans.len] / 10, ans.A[ans.len] %= 10, ans.len++;
    		return ans;
    	}
    	LL operator *= (const LL& t) {
    		*this = *this * t;
    		return *this;
    	}
    	LL operator * (const int& t) const {
    		LL ans = t;
    		return ans * (*this);
    	}
    	LL operator *= (const int& t) {
    		*this = *this * t;
    		return *this;
    	}
    	
    	bool operator < (const LL& t) const {
    		if(len != t.len) return len < t.len;
    		for(int i = len; i > 0; i--) if(A[i] != t.A[i]) return A[i] < t.A[i];
    		return 0;
    	}
    	bool operator > (const LL& t) const {
    		if(len != t.len) return len > t.len;
    		for(int i = len; i > 0; i--) if(A[i] != t.A[i]) return A[i] > t.A[i];
    		return 0;
    	}
    	bool operator == (const LL& t) const {
    		if(len != t.len) return 0;
    		for(int i = len; i > 0; i--) if(A[i] != t.A[i]) return 0;
    		return 1;
    	}
    	bool operator != (const LL& t) const {
    		return !((*this) == t);
    	}
    	bool operator <= (const LL& t) const {
    		return *this < t || *this == t;
    	}
    	bool operator >= (const LL& t) const {
    		return *this > t || *this == t;
    	}
    	
    	LL operator / (const LL& t) const {
    		LL ans, f = 0; ans.len = -1;
    		for(int i = 1; i <= len; i++) ans.A[i] = 0;
    		for(int i = len; i > 0; i--) {
    			f = f * 10 + A[i];
    			while(f >= t) {
    				f -= t; ans.A[i]++;
    				ans.len = max(ans.len, i);
    			}
    		}
    		return ans;
    	}
    	LL operator /= (const LL& t) {
    		*this = *this / t;
    		return *this;
    	}
    	LL operator / (const int& t) const {
    		LL ans; int f = 0; ans.len = -1;
    		for(int i = 1; i <= len; i++) ans.A[i] = 0;
    		for(int i = len; i > 0; i--) {
    			f = f * 10 + A[i];
    			while(f >= t) {
    				f -= t; ans.A[i]++;
    				ans.len = max(ans.len, i);
    			}
    		}
    		return ans;
    	}
    	LL operator /= (const int& t) {
    		*this = *this / t;
    		return *this;
    	}
    	
    	void print() {
    		if(len < 0){ putchar('0'); return ; }
    		for(int i = len; i > 0; i--) putchar(A[i] + '0');
    		return ;
    	}
    };
    
    LL f[maxn];
    LL C(LL n, int m) {
    	LL sum = 1;
    	for(LL i = n; i >= n - m + 1; i--) sum *= i;
    	for(int i = 1; i <= m; i++) sum /= i;
    	return sum;
    }
    LL dp(int n) {
    	LL& ans = f[n];
    	if(ans > 0) return ans;
    	if(!n) return ans = 1;
    //	printf("dp(%d)
    ", n);
    	for(int s1 = n - 1; s1 >= 0; s1--)
    		for(int s2 = s1; s2 >= 0; s2--) {
    			int s3 = n - s1 - s2 - 1;
    			if(s3 < 0) continue;
    			if(s2 < s3) break;
    //			printf("%d %d %d
    ", s1, s2, s3);
    			if(s1 == s3) ans += C(dp(s1) + 2, 3);
    			else if(s1 == s2)
    				ans += C(dp(s1) + 1, 2) * dp(s3);
    			else if(s2 == s3)
    				ans += C(dp(s2) + 1, 2) * dp(s1);
    			else ans += dp(s1) * dp(s2) * dp(s3);
    //			printf("dp(%d): %lld
    ", n, ans);
    		}
    //	printf("%d: %d
    ", n, ans);
    	return ans;
    }
    
    string Names[15] = {"¼×", "ÒÒ", "±û", "¶¡", "Îì", "¼º", "¸ý", "ÐÁ", "ÈÉ", "¹ï"};
    string getname(int n) {
    	if(n <= 10) return Names[n-1] + string("Íé");
    	char Name[maxn]; memset(Name, 0, sizeof(Name));
    	sprintf(Name, "%dÍé", n);
    	return string(Name);
    }
    
    int main() {
    	while(1) {
    		int n = read();
    		LL ans = 0, getrid = 0;
    		if(n & 1) {
    			for(int s1 = (n >> 1); s1 >= 0; s1--)
    				for(int s2 = s1; s2 >= 0; s2--)
    					for(int s3 = s2; s3 >= 0; s3--) {
    						int s4 = n - s1 - s2 - s3 - 1;
    						if(s4 < 0) continue;
    						if(s3 < s4) break;
    //						printf("%d %d %d %d
    ", s1, s2, s3, s4);
    						if(s1 == s4) ans += C(dp(s1) + 3, 4);
    						else if(s1 == s3) ans += C(dp(s1) + 2, 3) * dp(s4);
    						else if(s2 == s4) ans += C(dp(s2) + 2, 3) * dp(s1);
    						else {
    							int S[4] = {s1, s2, s3, s4}, l = 0, r = 0;
    							LL tmp = 1;
    							while(r < 4) {
    								while(r < 3 && S[l] == S[r+1]) r++;
    								tmp *= C(dp(S[l]) + r - l, r - l + 1);
    								l = r = r + 1;
    							}
    							ans += tmp;
    						}
    					}
    		}
    		else {
    			for(int s1 = (n >> 1) - 1; s1 >= 0; s1--)
    				for(int s2 = s1; s2 >= 0; s2--)
    					for(int s3 = s2; s3 >= 0; s3--) {
    						int s4 = n - s1 - s2 - s3 - 1;
    						if(s4 < 0) continue;
    						if(s3 < s4) break;
    //						printf("%d %d %d %d
    ", s1, s2, s3, s4);
    						if(s1 == s4) ans += C(dp(s1) + 3, 4);
    						else if(s1 == s3) ans += C(dp(s1) + 2, 3) * dp(s4);
    						else if(s2 == s4) ans += C(dp(s2) + 2, 3) * dp(s1);
    						else {
    							int S[4] = {s1, s2, s3, s4}, l = 0, r = 0;
    							LL tmp = 1;
    							while(r < 4) {
    								while(r < 3 && S[l] == S[r+1]) r++;
    								tmp *= C(dp(S[l]) + r - l, r - l + 1);
    								l = r = r + 1;
    							}
    							ans += tmp;
    						}
    					}
    			ans += C(dp(n >> 1) + 1, 2);
    		}
    		cout << getname(n); printf("ÓÐ "); ans.print(); puts(" ÖÖͬ·ÖÒì¹¹Ìå");
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    编译安装httpd
    ANSIBLE安装和常用模块模块使用详细教程
    MySQL集群高可用
    MySQL数据库备份和恢复
    MySQL数据库多表查询
    MySQL语句使用。
    MySQL多实例安装教程
    二进制安装MySQL数据库
    半自动化系统安装
    c语言分别用库函数和系统函数来进行文件操作效率对比
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6777649.html
Copyright © 2011-2022 走看看