# 1
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4
5 using namespace std;
6
7 long long s = 0;
8 // 点数最大不会超过 154
9 bool book[200];
10 int se[14]; // select
11
12 // 有点像DFS全排列的思路
13 void DFS2(int n, int num)
14 {
15 if(num > 13) return;
16 if(n == 14 && num != 13) return; //少了这句返回值错误
17 if(n == 14 && num == 13){
18 s++;
19 return;
20 }
21 // 必须从 0 开始, 表示可拿可不拿
22 for(int i=0;i<=4;i++)
23 DFS2(n+1, num+i);
24 }
25 // 3598180
26 // 结果出不来, 但是可以手算出来...怕不是这么简单
27 void DFS(int n, int score)
28 {
29 if(n == 14){
30 if(!book[score]){
31 s++;
32 book[score] = true;
33 // cout<<score<<'
';
34 }
35 return;
36 }
37 for(int i=1;i<=13;i++){
38 if(!se[i]) continue;
39 se[i]--;
40 DFS(n+1, score+i);
41 se[i]++;
42 }
43 }
44 // 154-28+1
45
46 int main()
47 {
48 memset(book, false, sizeof(book));
49 for(int i=1;i<=13;se[i++] = 4);
50 // C(52,13) = 635013559600
51 // DFS(1, 0); // 貌似思路不对, 是我打牌太差了
52 // DFS2(1, 0);
53 // cout<<s<<'
';
54 cout<<3598180<<'
';
55 return 0;
56 }
57
# 2
1 /*
2 - 其实就是一个不定方程
3 - 这里可以暴力法
4 - 事实上最正确的做法是扩展欧几里得算法
5 */
6 #include<iostream>
7 #include<cstdio>
8 #include<cstring>
9
10 using namespace std;
11
12 int main()
13 {
14 /*
15 for(int i=1;i<100;i++){
16 for(int j=1;j<100;j++){
17 if(i<j && i*2.3 + j*1.9 == 82.3)
18 cout<<i<<'
';
19 // cout<<i<<":"<<j<<'
';
20 }
21 }
22 */
23 cout<<11<<'
';
24
25 return 0;
26 }
27
# 3
1 #include<iostream>
2 #include<cstring>
3 #include<string>
4 #include<sstream>
5 #include<cstdlib>
6 #include<ctime>
7 #include<cstdio>
8
9 using namespace std;
10
11 int main()
12 {
13 // 找规律
14 cout<<(2*(1<<9)-1+2)<<'
';
15
16 return 0;
17 }
# 4
1 #include<iostream>
2
3 using namespace std;
4
5 int c = 0;
6
7 void fun(int i, int j, int k)
8 {
9 // 最后遇到花,还剩一抖酒
10 if(i == 0 && j == 1 && k == 1){
11 c++;
12 return;
13 }
14 if(i>0) fun(i-1, j, k*2);
15 if(j>0) fun(i, j-1, k-1);
16 }
17
18 int main()
19 {
20 // fun(5,10,2);
21 // 14
22 cout<<14<<endl;
23
24 return 0;
25 }
# 5 说好的对称呢
1 #include<iostream>
2 #include<cstdio>
3
4 using namespace std;
5
6 bool sure(int i, int j, int k, int z)
7 {
8 // 注意题目要求
9 if(i == j || k == z) return false;
10 int lu = i*k;
11 int ld = j*z;
12 int ru = i*10+k;
13 int rd = j*10+z;
14 // 小心浮点数
15 return lu*rd == ld*ru;
16 }
17
18 int main()
19 {
20
21 /*
22 long long c = 0;
23 for(int i=1;i<=9;i++){
24 for(int j=1;j<=9;j++){
25 for(int k=1;k<=9;k++){
26 for(int z=1;z<=9;z++){
27 if(sure(i, j, k, z)){
28 // printf("%d/%d * %d/%d = %d/%d
", i, j, k, z, i*10+k, j*10+z);
29 c++;
30 }
31 }
32 }
33 }
34 }
35 */
36
37 // cout<<2*c<<'
';
38 cout<<2*14<<'
';
39 return 0;
40 }
41
# 6
1 #include<iostream>
2 #include<cstdio>
3
4 using namespace std;
5
6 int n = 0;
7
8 // A1 = (1 - sin(1))
9 void An(int n, int k)
10 {
11 if(n == 1){
12 printf("sin(%d", k);
13 return;
14 }
15 printf("sin(%d%c", k, (k&1)?'-':'+');
16 An(n-1, k+1);
17 printf(")");
18 }
19
20 void Sn(int n, int k, int z)
21 {
22 if(k == n){
23 return;
24 }
25 printf("(");
26 Sn(n, k+1, z+1);
27 {
28 An(n-k, 1);
29 printf(")");
30 printf("+%d)", z+1);
31 }
32
33 }
34
35 int main()
36 {
37 while(cin>>n)
38 {
39 Sn(n, 1, 1);
40 An(n, 1);
41 printf(")+1
");
42 }
43
44 return 0;
45 }
46
47 // ((sin(1)+3)sin(1-sin(2))+2)sin(1-sin(2+sin(3)))+1
48 // ((sin(1)+3)sin(1-sin(2))+2)sin(1-sin(2+sin(3)))+1
# 7 类似最大子阵,dp法
# 8
1 /*
2 - 初见,内存也足够,桶排序的话时间也够
3 - 难点在于换行输入的处理,一般的输入会吃掉换行符
4 - 这不是算法的初衷......
5 */
6 #include<iostream>
7 #include<cstring>
8 #include<cstdio>
9 #include<string>
10 using namespace std;
11
12 const int MAX = 100001;
13 int t[MAX];
14 int s = MAX, e = 0;
15
16 // 整数快速幂
17 int pow(int x, int n)
18 {
19 if(n == 0) return 1;
20 int s = 1;
21 while(n)
22 {
23 if(n&1) s *= x;
24 x *= x;
25 n >>= 1;
26 }
27 return s;
28 }
29
30 void join(string x)
31 { // 手动分词吧,反向迭代器可以避免考虑数的位数
32 string::reverse_iterator rite;
33 int i = 0, n = 0;
34 rite = x.rbegin();
35 while(rite!=x.rend())
36 {
37 if(*rite == ' '){
38 if(i < s) s = i;
39 if(i > e) e = i;
40 rite++;t[i]++;
41 i = 0;n = 0;
42 continue;
43 }
44 i += (int(*rite)-'0') * pow(10, n);n++;
45 rite++;
46 }
47 return;
48 }
49
50 int main()
51 {
52 int n;
53 string temp;
54 while(cin>>n)
55 { getline(cin, temp); // 这是关键,接收输入n时多出的回车
56 memset(t, 0, sizeof(t));
57 for(int i=0;i<n;i++){
58 // 逼急了,直接上getline
59 // 尽管C++有它自己的分词工具,这里就涉及到我的知识盲区了
60 string x;
61 getline(cin, x, '
');
62 x = ' ' + x; // 注意补充空格
63 join(x);
64 }
65 int ans[2] = {0};
66 for(int i=s;i<=e;i++){
67 if(t[i] == 0) ans[0] = i;
68 if(t[i] == 2) ans[1] = i;
69 }
70 cout<<ans[0]<<" "<<ans[1]<<endl;
71 }
72
73 return 0;
74 }
# 9
1 /*
2 * N = A + B/C
3 * A 最长不超过7位数, 这样我们确定一个 A
4 * 然后我们可以知道 C 的最后一位为 a[8]
5 * 通过计算我们可以确定 B 的 最后一位 b_end = (N - A)*a[8]%10
6 * 如此,我们就知道了 C 为多少
7 * 最后,判断一下是否满足等式
8 */
9 #include<iostream>
10 #include<algorithm>
11
12 using namespace std;
13
14 int c = 0,N = 0;;
15 int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
16
17 // 这里复习一下整数快速幂,就不调用数学库了
18 // O(log2N)
19 int pow(int x, int n)
20 {
21 int s = 1;
22 while(n)
23 {
24 if(n&1) s *= x;
25 x *= x;
26 n >>= 1;
27 }
28 return s;
29 }
30
31 // A、B、C, b开始, e-1结束的一段数组
32 int PI(int b, int e)
33 {
34 int s = 0, k = e-b-1;
35 while(b!=e)
36 {
37 s += a[b]*pow(10, k);k--;b++;
38 }
39 return s;
40 }
41
42 // 获取 B 最后一位的 local
43 int getB_end(int x)
44 {
45 int loc = 0;
46 for(int i=0;i<9;i++)
47 if(a[i] == x)
48 return i;
49 }
50
51 void solve(int *a, int N)
52 {
53 int A, B, C;A = B = C = 0;
54 // cout<<N<<endl;
55 for(int i=1;i<=7;i++){
56 A = PI(0, i);
57 int B_end = ((N - A)*a[8])%10;
58 int loc = getB_end(B_end);
59 if(loc < i || loc >= 8)
60 continue;
61 // Ai! 这里注意一下是 loc + 1
62 B = PI(i, loc+1);
63 C = PI(loc+1, 9);
64 // cout<<A<<":"<<B<<":"<<C<<endl;
65 // cout<<A<<":"<<B<<":"<<C<<endl;
66 if(A*C + B == N*C){
67 // cout<<A<<":"<<B<<":"<<C<<endl;
68 c++;
69 }
70 }
71 }
72
73 int main()
74 {
75 while(cin>>N)
76 {
77 while(next_permutation(a, a+9))
78 { // 时间复杂度可以看成 O(9!)
79 solve(a, N);
80 // break;
81 }
82 cout<<c<<endl;c = 0;
83 }
84 return 0;
85 }
# 10 以前看过别人的博客,我比较菜但是并没有研究看懂,只记得也是一个动态规划问题
2019-03-09
14:01:12