【TFLSnoi李志帅】第十⑥篇文章---难题求解

遇见几道难题,求解!

遇见几道难题,求解!

 

遇见几道难题,求解!

 

①.I - 数字组合(课后作业)

 

现在小瓜有1到n这n个整数,他想知道用这n个整数组成一个长度为n的数字序列的所有方法(每个整数可以重复使用)。你能帮助他吗?

Input

一行一个整数n(1<=n<=6)。

Output

若干行,每行表示用1到n组成一个长度为n的数字序列的一种方法。所有方法按字典序输出。

Sample Input

2

Sample Output

1 1
1 2
2 1
2 2


————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————


我的垃圾骗分代码:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     long long n;
 6     cin>>n;
 7     if(n==1)cout<<1;
 8     if(n==2){
 9         cout<<"1 1"<<endl;
10         cout<<"1 2"<<endl;
11         cout<<"2 1"<<endl;
12         cout<<"2 2"<<endl;
13     }
14     if(n==3){
15         for(int i=1;i<=3;i++){
16             for(int j=1;j<=3;j++){
17                 for(int k=1;k<=3;k++)
18                 cout<<i<<" "<<j<<" "<<k<<endl;
19             }
20         }
21     }
22     if(n==4){
23         for(int i=1;i<=4;i++){
24             for(int j=1;j<=4;j++){
25                 for(int k=1;k<=4;k++){
26                     for(int a4=1;a4<=4;a4++)cout<<i<<" "<<j<<" "<<k<<" "<<a4<<endl;
27                 }
28                 
29             }
30         }
31     }
32     if(n==5){
33         for(int i=1;i<=5;i++){
34             for(int j=1;j<=5;j++){
35                 for(int k=1;k<=5;k++){
36                     for(int a4=1;a4<=5;a4++){
37                         for(int a5=1;a5<=5;a5++)cout<<i<<" "<<j<<" "<<k<<" "<<a4<<" "<<a5<<endl;
38                     }
39                 }
40                 
41             }
42         }
43     }
44     if(n==6){
45             for(int i=1;i<=6;i++){
46             for(int j=1;j<=6;j++){
47                 for(int k=1;k<=6;k++){
48                     for(int a4=1;a4<=6;a4++){
49                         for(int a5=1;a5<=6;a5++){
50                             for(int a6=1;a6<=6;a6++)cout<<i<<" "<<j<<" "<<k<<" "<<a4<<" "<<a5<<" "<<a6<<endl;
51                         }
52                     }
53                 }
54                 
55             }
56         }
57     }
58     return 0;
59 }

因为数据规模较小,所以侥幸过了

 

再来看看别人的代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <climits>
 6 #include <cstring>
 7 #include <string>
 8 #include <algorithm>
 9 #include <vector>
10 #include <deque>
11 #include <list>
12 #include <utility>
13 #include <set>
14 #include <map>
15 #include <stack>
16 #include <queue>
17 #include <bitset>
18 #include <iterator>
19 using namespace std;
20 
21 typedef long long ll;
22 const int inf = 0x3f3f3f3f;
23 const ll  INF = 0x3f3f3f3f3f3f3f3f;
24 const double PI = acos(-1.0);
25 const double E = exp(1.0);
26 const int MOD = 1e9+7;
27 const int MAX = 1e5+5;
28 int n;
29 int a[6+5];
30 
31 void dfs(int i)
32 {
33     if(i == n)
34     {
35         for(int j = 0; j < n; j++)
36             cout << a[j] << " ";
37         cout << endl;
38         return;
39     }
40     for(int k = 1; k <= n; k++)
41     {
42         a[i] = k;
43         dfs(i+1);
44     }
45 }
46 
47 int main()
48 {
49     ios::sync_with_stdio(false);
50     cin.tie(0);
51     cout.tie(0);
52 
53     while(cin >> n)
54     {
55         dfs(0);
56     }
57 
58     return 0;
59 }

我发现我看不懂啊!!!

我发现我看不懂啊!!!

我发现我看不懂啊!!!(重要的事情说三遍

 

所以。。。求解啊!感谢

所以。。。求解啊!感谢

所以。。。求解啊!感谢

 

 

 

 

 

——————————————————————————————————————————————————————————————————————————

②.C - 最长回文子串(课后作业)

 

输入一个字符串Str,输出Str里最长回文子串的长度。

 

回文串:指aba、abba、cccbccc、aaaa这种左右对称的字符串。

 

串的子串:一个串的子串指此(字符)串中连续的一部分字符构成的子(字符)串
例如 abc 这个串的子串:空串、a、b、c、ab、bc、abc

Input

输入Str(Str的长度 <= 1000)

Output

输出最长回文子串的长度L。

Sample Input

daabaac

Sample Output

5


——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————-
我真的是写不出来
再看看别人的:
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 char str[1000002 + 1200];
 6 int fast(char *p) {
 7     int ans = 1;
 8     for (int i = 1; p[i]; ++i) {
 9         int s = i, e = i, t;
10         while(p[e+1] == p[i]) {
11             ++e;
12         }
13         i = e;
14         while(p[s-1] == p[e+1]) {
15             --s;
16             ++e;
17         }
18         if((t = e-s+1) > ans) {
19             ans = t;
20         }
21     }
22     return ans;
23 }
24 int main() {
25     str[0] = '$';
26     while (cin>>(str+1)) {
27         cout<<fast(str)<<endl;
28     }
29     return 0;
30 }

???

有一点看不懂,这是用了指针吗?

 

还有这一篇

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 int main() {
 5     char s[1005], t[2010];
 6     memset(t, 0, sizeof(t));
 7     cin>>s;
 8     int length = strlen(s);
 9     int k = 0;
10     t[0] = '#';
11     for(int i = 1; i <= 2*length - 1; i+=2) {
12         t[i] = s[k++];
13         t[i+1] = '#';
14     }
15     int l, r, temp, max = 0;
16     for(int i = 0; i <= 2*length; i++) {
17         l = r = i;
18         if(l==0 || r==2*length) {
19             temp = 1;
20         } else {
21             while(t[l]==t[r]) {
22                 l--;
23                 r++;
24             }
25             temp = r-l;
26         }
27         if(temp > max) {
28             max = temp;
29         }
30     }
31     cout<<(max-1)/2<<endl;
32     return 0;
33 }

看倒是能看懂了,但是我不明白它的算法思想啊QAQ

 

 

 

————————————————————————————————————————————————————————————————————————

③.H - 全排列(课后作业)

 

输入一个整数n(n <= 9),输出1、2、3、······、n这n个数的全排列(按照字典序输出)。

Input

一个整数n

Output

多行,每行表示一种排列,行内使用空格分隔相邻两数。

Sample Input

3

Sample Output

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1




——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————-
本来我试图列表骗分,但是发现太长了,手要断了还没列出了。。。
所以,还是看看别人的代码叭:
 1 #include<iostream>
 2 using namespace std;
 3 int a[10];
 4 bool vis[10]={0};
 5 void dfs(int x, const int& m)//x计数以搜索的数的个数 
 6 {
 7     if(x>m)//搜索数目足够是输出所有的数 
 8     {
 9         for(int i=1;i<=m;i++)
10             cout<<a[i]<<' ';
11         cout<<endl;
12         return;
13     }
14     for(int i=1;i<=m;i++)
15         if(!vis[i])//判断数i是否已经被载入数组 
16         {
17             a[x]=i;
18             vis[i]=1;
19             dfs(x+1,m);
20             vis[i]=0;
21         }
22 }
23 
24 int main()
25 {
26     int n;
27     cin>>n; 
28     dfs(1,n); 
29     return 0;
30  } 

哦,还有他的分析:

 

分析过程

 

初步涉及算法,描述错误,还请担待。
首先,这是使用的是dfs算法,向着一种情况不断的深入直至找到答案再到下一种情况不断延伸。这里的思路是用dfs分别找到每一位应该放的数。

 

这仅作本人笔记使用,有什么不足的地方还请指出,谢谢!

???

???

???

感觉这几道题好针对萌新啊

没办法,继续求解

 

 

————————————————————————————————————————————

 

最后一道:

④.J - 选数字(进阶习题)

 

从1-n中选出m个数,要求同样的数字不能重复选择,按照字典序正序输出所有方案。

 

例如:从1到4中选出2个数,共有6种方法,按照字典序输出,依次为:

 

1 2
1 3
1 4
2 3
2 4
3 4

Input

输入共2个数m, n,中间用空格分隔。(1 <= m <= n <= 20)

Output

按照字典序正序输出所有方案。

Sample Input

4 2

Sample Output

1 2
1 3
1 4
2 3
2 4
3 4


————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
写不出来,搜到一个,结果发现是Java版的。。。

又发现个c++版的,结果咋又用上指针了?QAQ
 1 void SelectK_01(int n,int k)
 2 {
 3     //true is selected
 4     bool *nselect = (bool *)malloc(n*sizeof(bool));
 5     
 6     int i = 0;
 7     
 8     //初始化第一个组合,即选择前k个数 
 9     while(i<n)
10     {
11         if(i<k)
12          nselect[i] = true;
13         else
14          nselect[i] = false;
15         i++;
16     }
17     
18     i = 0;
19     while(i<n){
20         if(nselect[i]) printf(" %d ",i+1);
21         i++;
22     }
23     printf("\n");
24     
25     i=0;
26     while(i<n-1)
27     {
28         //找到第一个10组合,并交换10的位置 
29         if(nselect[i] && !nselect[i+1])
30         {
31             int temp = nselect[i];
32             int x=0,y=0;
33             nselect[i] = nselect[i+1];
34             nselect[i+1] = temp;
35             //将该组合左边所有的1移至数组最左边 
36             while(y<i)
37             {
38                 if(nselect[y])
39                 {
40                     temp = nselect[y];
41                     nselect[y] = nselect[x];
42                     nselect[x] = temp;
43                     x++;
44                 }
45                 y++;
46             }
47             
48             i = 0;
49             while(i<n){
50                 if(nselect[i]) printf(" %d ",i+1);
51                 i++;
52             }
53             printf("\n");
54             
55             i = (x==0?0:x-1);
56         }
57         else i++; 
58     }
59     free(nselect);
60 }
61  

还有那个free。。。?

好不容易找见个c++递归版的,结果。。。

 1 //d存储选择的数,NUM指示选择多少个数,即初始k的大小
 2 void Recursive_SelectK(int n,int k,int d[],const int NUM)
 3 {
 4     int i = n;
 5     if(k > n) return;
 6     while(i>=k)
 7     {
 8         d[NUM-k] = i;
 9         if(k>1) Recursive_SelectK(i-1,k-1,d,NUM);
10         else
11         {
12             int j = 0;
13             while(j<NUM)
14             {
15                 printf("%d ",d[j]);
16                 j++;
17             }
18             printf("\n");
19         }
20         i--;
21     }
22 }

有点没法理解QAQ

强制性微笑………^V^

求解啊!!!

 

posted @ 2020-08-20 15:52  九州霜  阅读(421)  评论(0编辑  收藏  举报