#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define ll long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl const double PI = acos(-1.0); #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif int n; int record[10010]; int a[10010]; while(scanf("%d", &n) != EOF) { memset(record, , sizeof(record)); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n;i ++) for(int j = i+1; j <= n; j++) { if(a[j] % a[i] == ) { record[i] = j; break; } } // debug(record, n+1); ll res = ; for(int i = 1; i <= n; i++) res += record[i]; printf("%lld\n", res); } return ; }
ACM – UVa10006 – 快速幂
水题一发。无奈自己没有好好审清题意,另外快速幂居然写错了- =
快速幂在过程中修改a的值,但是我却计算成了在偶数时相乘,调试半天。看来还是咩有好好理解啊。
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define ll long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl const double PI = acos(-1.0); #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } ll p; ll pow_mod(ll a, ll n) { ll ans = 1; a %= p; while(n) { if(n & 1) ans = ans * a % p; a = a * a % p; n >>= 1; } return ans; } // 3. const int maxn = 10000000 + 10; const int maxp = 700000; int vis[maxn]; int prime[maxp]; // 筛素数 void sieve(int n) { int m = (int) sqrt(n+0.5); memset(vis, , sizeof(vis)); for(int i = 2; i <= m;i ++) if(!vis[i]) for(int j = i*i; j <= n; j+=i) vis[j] = 1; } // 生成素数表 int gen_primes(int n) { sieve(n); int c = ; for(int i = 2; i <= n; i++) if(!vis[i]) prime[c++] = i; return c; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif ll n; const int bound = 65000+10; gen_primes(bound); while(scanf("%lld", &n) && n!= ) { // p is mod p = n; if(!vis[n]) printf("%lld is normal.\n", n); else { bool find = 1; for(ll i = 2; i < n;i ++) if(pow_mod(i, n) != i) { find = ; break; } if(find) printf("The number %lld is a Carmichael number.\n", n); else printf("%lld is normal.\n", n); } } return ; }
ACM – UVa138 – 数学基础
这道题目其实就是推个公式,主要还是考验编程技巧。。
首先double的精度范围是15-16位,浮点数运算还是最快的,依据最后一个答案(总共10组),平方为16位刚好够用。
如果想要最精确的结果,当然还是使用long double或者long long来来保证精度问题。不过计算速度就会有所损失,采取二分的方法加速比较好。
利用double的代码:
const double eps = 1e-10; for(double i = 8; i < maxn;i ++) { double res = i*(i+1)/2; ll ans = sqrt(res); if(res - ans*ans < eps) printf("%10lld %10lf\n", ans, i); } printf("done");
利用long long的代码:
for(ull i = 8; i < maxn;i ++) { ull res = i*(i+1)/2; ull l = i/2, r = i; ull mid, ans; bool find = ; // bsearch while(l <= r) { mid = (l+r)/2; ans = mid * mid; if(ans == res) { find = 1; break; } else if(ans > res) r = mid - 1; else l = mid + 1; } if(find) printf("%10lld %10lld\n", mid, i); } printf("done");
不过有一点就是无论怎么个快法,不使用打表肯定是会超时的,所以算出来直接上交即可。= =。这在大赛中应该也是允许的吧。
山东省第五届省赛 Circle
首先一点什么是高斯消元?
高斯消元其实就是一种求行列式的值的方法。
例如
|a[0][0]_x1 + a[0][1]_x2+ … a[0][n-1]_xn = a[0][n]|
|a[1][0]_x1 + a[1][1]_x2+ … a[1][n-1]_xn = a[1][n]|
|a[2][0]_x1 + a[2][1]_x2+ … a[2][n-1]_xn = a[2][n]|
|a[3][0]_x1 + a[3][1]_x2+ … a[3][n-1]_xn = a[3][n]|
…
|a[n-1][0]_x1 + a[n-1][1]_x2+ … a[n-1][n-1]*xn = a[n-1][n]|
已知a[x][y],求x1, x2 .. xn的值。这个时候就可以使用高斯消元。
本题目就是高斯消元求解的一道题目。
依据题意,可以列出方程:
$$E[x] = 0.5_(E[x-1]+1) + 0.5_(E[x+1]+1)$$
其中E代表期望,利用高斯消元我们可以得到x1-xn的值,输出我们需要的E[x]即可。
高斯消元其实就是我们所说的消元,但是针对于大型的矩阵。
倒是很简单的题目。
山东省第五届省赛 Hearthstone II
斯特林数stirling
- 第一类 stirling数 s(n, k)
n个人分成k组,组内再按特定顺序围圈
也就是分成了k组,组内就像是项链颜色一样,
- ( {A, B}, {C, D} )
- ( {B, A}, {C, D} )
属于一组
- ({A}, {B, C, D})
- ({A}, {B, D, C})
不属于一组
给定 $s(n,0)=0,s(1,1)=1$,有递归关系$s(n,k)=s(n-1,k-1) + (n-1) s(n-1,k)$
- 第二类 stirling数
S(n, k) 是把p元素集合划分到k个不可区分的盒子里且没有空盒的划分个数。
公式:
$$ S(n, n) = 1 (n >= 0) $$
$$ S(n, 0) = 0 (n >= 1) $$
$$ S(n,k)=k*S(n-1,k)+S(n-1,k-1),\text (1<=k<=n-1) $$
这样题目就好解决了。第五届省赛题目神经病。
因为每个桌子是不同的,所以还要利用乘法原理,$ans*m!$
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl const double PI = acos(-1.0); #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } #define mod 1000000007 const int maxn = 100 + 10; lln s[maxn][maxn]; void init() { for(int i = ; i < 101; i++) { s[i][] = ; s[i][i] = 1; } for(int n = 2; n < 101; n++) for(int k = 1; k <= n-1 ; k++) s[n][k] = ((k*s[n-1][k])%mod + s[n-1][k-1]%mod) %mod; } int readinput() { int m, n; if(scanf("%d%d", &n, &m) == EOF) return ; else { lln ans = s[n][m]; for(int i = 2; i <= m; i++) { ans *= i; ans %= mod; } printf("%lld\n", ans); } return 1; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif init(); while(readinput()); return ; }
山东省第五届ACM省赛 Weighted Median
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define inf 0x3f3f3f3f #define lln long long int #define mem(a) memset(a, 0, sizeof(a)) #define memm(a) memset(b, -1, sizeof(b)) #define deb(x, n) cout << (x) << " " << (n) << endl #define cr printf("\n") // 调试用 template <class type> void debug(type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } const int maxn = 10000000+10; lln sum[maxn]; struct ele { lln x, w; }; int cmp(ele a, ele b) { return a.x < b.x; } ele e[maxn]; int main() { #ifdef debug // freopen("input", "r", stdin); #endif int n; while(scanf("%d", &n) != eof) { for(int i = ; i < n; i++) scanf("%lld", &e[i].x); for(int i = ; i < n; i++) scanf("%lld", &e[i].w); sort(e, e+n, cmp); sum[] = e[].w; for(int i = 1; i < n;i ++) sum[i] = e[i].w + sum[i-1]; double sm = sum[n-1]/2.0; bool flag; int i; for(i = ; i < n; i++) { int ti, tj; ti = tj = i; if(i != ) while(e[ti].x == e[ti-1].x) ti--; else ti = -1; if(i != n-1) while(e[tj].x == e[tj+1].x) tj++; else tj = n; flag = 1; // wi <= s/2 if(ti == -1) {} else if(sum[ti-1] <= sm) {} else flag = ; // wi < s/2 if(tj == n) {} else if (sum[n-1] - sum[tj] < sm){} else flag = ; if(flag) break; i = tj; } printf("%lld\n", e[i].x); } return ; }
bestcoder#2-1
一开始直接使用结构体搞结果wrong了,随后查看了某牛的代码发现应该直接在区间上累加 — 得出结论不要直接使用复杂的结构体,转变成简单的数据形式未尝不是一个好方法
原题:
http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=526&pid=1001
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } const int maxn = 10000 + 10; int main() { #ifdef DEBUG // freopen("input", "r", stdin); #endif int T, n; // 24 * 60 + 60 = 1500 int a[2000], s1, s2, e1, e2; int num; scanf("%d", &T); while(T--) { scanf("%d", &n); int maxx = ; memset(a, , sizeof(a)); for(int i = ; i < n;i++) { scanf("%d%d:%d%d:%d", &num, &s1, &s2, &e1, &e2); int sum1 = s1*60 + s2; int sum2 = e1*60 + e2; for(int j = sum1; j < sum2; j++) { a[j] += num; maxx = max(maxx, a[j]); } } printf("%d\n", maxx); } return ; }
蓝桥杯基础练习
数列排序
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif int n; const int maxn = 200 + 10; int a[maxn]; while(cin >> n) { for(int i = ; i < n; i++) cin >> a[i]; sort(a, a+n); for(int i = ; i < n; i++) printf("%d%c", a[i], i == n-1? '\n': ' '); } return ; }
十六进制转八进制
转换的时候,先转换成二进制,再转换成十六进制。
这道题目还是比较有意思的,使用string只需要78ms,使用char*则超时。可能strcat每次都需要从头遍历数组,但是string则不需要。
当然,如果是数字没有这么大,完全可以这样处理
lln a; scanf("%x", &a); printf("%o", a);
是不是很精髓= =
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } const char t2[16][9] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; const char t8[8][8] = { "000", "001", "010", "011", "100", "101", "110", "111" }; const int maxn = 400000+10; void trans(char *num) { string temp; // char temp[maxn] = {'\0'}; int len = strlen(num); int len2 = ; for(int i = ; i < len;i ++) { int t; if(num[i] >= '0' && num[i] <= '9') t = num[i] - '0'; else t = num[i] - 'A' + 10; // strcat(temp, t2[t]); temp += t2[t]; } int cnt = ; len = temp.length(); // len = strlen(temp); int i; for(i = len-3; i >= ; i-=3) for(int j = ; j < 8; j++) { bool test = 1; for(int k = ; k < 3; k++) if(t8[j][k] != temp[i+k]) { test = ; break; } if(test) { num[cnt++] = j+'0'; break; } } if(i == -1) for(int j = ; j < 7;j ++) { bool test = 1; for(int i = 1; i < 3; i++) { if(t8[j][i] != temp[i-1]) { test = ; break; } } if(test) { num[cnt++] = j+'0'; break; } } else if(i == -2) for(int j = ; j < 7;j ++) { if(t8[j][2] == temp[]) { num[cnt++] = j+'0'; break; } } num[cnt] = '\0'; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif int n; cin >> n; char num[maxn]; for(int i = ; i < n;i ++) { scanf("%s", num); trans(num); int len = strlen(num); int j; for(j = len-1; j >= ; j--) if(num[j] != '0') break; for(;j >= ; j--) cout << num[j]; cout << endl; } return ; }
十六进制转十进制
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif lln a; while(scanf("%I64X", &a) != EOF) { printf("%I64d\n", a); } return ; }
十进制转十六进制
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif lln a; while(scanf("%I64d", &a) != EOF) { printf("%I64X\n", a); } return ; }
由此也可以想到,如果是二进制的相关转换(数值范围允许的情况),我们可以写一个简单二进制转十六进制,然后利用sscanf来做进一步转换。
[阅读全文]蓝桥杯入门训练题目
蓝桥的系统需要I64d这种输入格式。无力吐槽。
Fibonacci数列
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif int n; while(scanf("%d", &n) != EOF) { int pre = 1, mid = 1; int temp; if(n == 2 || n == 1) { puts("1"); continue; } for(int i = 2; i < n;i ++) { temp = pre + mid; temp %= 10007; pre = mid; mid = temp; } printf("%d\n", temp); } return ; }
圆的面积
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif double PI = acos(-1.0); int r; while(scanf("%d", &r) != EOF) { double res = PI * r *r; printf("%.7lf\n", res); } return ; }
序列求和
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif lln n; while(scanf("%I64d", &n) != EOF) { printf("%I64d\n", (1+n)*n/2); } return ; }
A+B
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <bitset> using namespace std; // 大数,内存处理 #define INF 0x3f3f3f3f #define lln long long int #define MEM(a) memset(a, 0, sizeof(a)) #define MEMM(a) memset(b, -1, sizeof(b)) #define DEB(x, n) cout << (x) << " " << (n) << endl #define CR printf("\n") // 调试用 template <class Type> void debug(Type a[], int len) { for(int i = ; i < len ; i++) { cout << a[i] << " "; } cout << endl; } int main() { #ifdef DEBUG // freopen("input", "r", stdin); //从input文件中读入 // freopen("output", "w", stdout); //输出到output文件 #endif int a, b; while(scanf("%d%d", &a, &b) != EOF) { printf("%d\n", a+b); } return ; }
ACM – 快速生成测试数据
比赛的时候出现了100 * 100组数据的情况,但是当时使用freopen忘记了具体的步骤,特意重新写一下,也是属于基础的内容。
生成一百行数据,每行100个数据,每个数据为100。
#include <stdio.h> #include <iostream>`enter code here` using namespace std; int main() { freopen("input", "r", stdin); freopen("output", "w", stdout); for(int i = ; i < 100; i++) for(int j = ; j < 100; j++) printf("%d%c", 100, j == 99? '\n' : ' '); fclose(stdin); fclose(stdout); return ; }
运行过后生成的数据(本来应该输出在屏幕上,此时不会输出到屏幕,而是输出到文件)会保存到output
文件中。如果需要使用直接更改output
的文件名,再使用一次freopen('r')
即可。