第十七节 图论 - 2

AT_tenka1_2015_qualB_b 题解

洛谷链接&Atcoder 链接

本篇题解为此题较简单做法较少码量,并且码风优良,请放心阅读。

题目简述

给定一个集合形式,判断此集合是 dict 还是 set

思路

简单的模拟题

首先需要特判 {} 的情况,应直接输出 dict

接着观察两个集合的特征,很容易即可发现 dictset 的最明显的区别就是一个有 : 一个没有,而我们需要注意 expr 可是任何集合或者数字,所以有可能出现 {1,{2:3}} 的情况,而这种情况就不能直接看有无冒号进行判断了

我们需要用 \(num\) 来记录当前是第几层括号,如果在第一层括号中发现了冒号,那么这个集合就是 dict 了,反之就是 set

经过以上分析,很容易即可写出代码了:

#include<iostream>
using namespace std;

string str;

int main() {
	cin >> str;
  	// 特判 {} 的情况
	if(str.length() == 2) {
		cout << "dict\n";
		return 0;
	}
	int num = 0; // num 记录层数
	for(int i = 0; i <= str.length(); i ++) {
		if(str[i] == '{') num ++; // 遇到 { 层数加 1
		if(str[i] == '}') num --; // 遇到 } 层数减 1
		if(str[i] == ':' && num == 1) {
			cout << "dict\n"; // 最外层遇到 :
			return 0;
		}
	}	
	cout << "set\n"; // 换行好习惯
	return 0;
}

提交记录

\[\text{The End!} \]

CF709B 题解

洛谷链接&CF 链接

本篇题解为此题较简单做法较少码量,并且码风优良,请放心阅读。

题目简述

给定 \(N\) 个点,在一条数轴上,位置为 \(x_1,…,x_n\),你的位置为 \(p\),你要经过 \(N-1\) 个点,求至少要走的距离。

思路

首先因为输入是乱序的,所以需要由小到大排序

又因为需要经过 \(N-1\) 个点,所以要么不走左端点,要么不走右端点,这样分两种情况讨论,分别求出答案取 \(\min\) 即可。

首先分析情况 \(1\),要么 \(p \le a_2 \le a_n\),要么 \(a_2 \le p \le a_n\),要么 \(a_2 \le a_n \le p\)第二种不论先去 \(a_2\) 还是 \(a_n\) 结果都一样。所以不讨论,第一三种需要讨论一下,对于第一种一定是先去 \(a_2\) 结果最小, 对于第三种一定是先去 \(a_n\) 结果最小,只需对这两种分别处理最后取 \(\min\) 即可,由此分析可得这种情况的方程式为:

\[\min( | a_n - p | + | a_n - a_2 |, | a_2 - p | + | a_n - a_2 | ) \]

同样分析可得情况 \(2\)方程式

\[\min( | a_{n - 1} - p | + | a_{n - 1} - a_1 |, | a_1 - p | + | a_{n - 1} - a_1 | ) \]

最后对两种情况取 \(\min\) 即可。

经过以上分析,很容易即可得出代码了:

#include<iostream>
#include<algorithm>
using namespace std;

int n, a[100005], p;
long long ans = 0x3f3f3f3f; // 要取 min 所以需初始化一个较大数

int min(int x, int y) { return (x < y) ? x : y; }

int abs(int x) { return (x > 0) ? x : -x; }

int main(){
	cin >> n >> p;
	if(n == 1) { cout << "0\n"; return 0; } // 特判
	for(int i = 1; i <= n; i ++) cin >> a[i];
	sort(a + 1, a + n + 1); // 因为是乱序,所以需要排序
	long long num1 = 0, num2 = 0; // 可不开 long long
	// 情况 1
  	num1 = min(abs(a[n] - p) + abs(a[n] - a[2]), abs(a[2] - p) + abs(a[n] - a[2]));
  	// 情况 2
	num2 = min(abs(a[n - 1] - p) + abs(a[n - 1] - a[1]), abs(a[1] - p) + abs(a[n - 1] - a[1]));
	ans = min(num1, num2); // 答案取 min
	cout << ans << endl; // 输出,换行好习惯
	return 0;
}

提交记录:

SonoSlack

\[\text{The End!} \]

A. 小埋学习图之图的遍历

时间:1s 空间:512M

题目描述

小埋最近在学习有向图的遍历相关知识,小埋学习过图的遍历的相关方法,可以使用 \(\text{dfs}\) 或者 \(\text{bfs}\) 来遍历整个有向图,但是小埋发现这个问题有一些不一样,这个图的遍历是问你当前点能够到达的点的最大编号,小埋希望你能帮她解决这个问题。

输入格式

第一行两个整数一个 \(n\) 一个 \(m\)\(n\) 代表有向图中有 \(n\) 个点,\(m\) 代表有向图中有 \(m\) 条有向边。

接下来是 \(m\) 条边。

输出格式

输出每个点能够到达的最大编号

样例1输入

4 3
1 2
1 3
2 3

样例1输出

3 3 3 4

数据范围

\(1 \le n,m \le 100000\)

点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;
int n, m, fr, to;
int vis[100005];
vector<int> v[100005];

void dfs(int x, int y) {
	for (int i = 0; i < v[x].size(); i ++) {
		if(vis[v[x][i]]) continue;
		vis[v[x][i]] = y;
		dfs(v[x][i], y);
	}
	return;
}

int main() {
	scanf("%d %d", &n, &m);
	while (m --) {
		scanf("%d %d", &fr, &to);
		v[to].push_back(fr);
	}
	for (int i = n; i >= 1; i --)
		if (!vis[i]) vis[i] = i, dfs(i, i);
	for (int i = 1; i <= n; i ++) printf("%d ", vis[i]);
	return 0;
}
编译结果
compiled successfully
time: 328ms, memory: 8272kb, score: 100, status: Accepted
> test 1: time: 0ms, memory: 5976kb, points: 10, status: Accepted
> test 2: time: 39ms, memory: 8168kb, points: 10, status: Accepted
> test 3: time: 38ms, memory: 8008kb, points: 10, status: Accepted
> test 4: time: 24ms, memory: 7392kb, points: 10, status: Accepted
> test 5: time: 40ms, memory: 8272kb, points: 10, status: Accepted
> test 6: time: 30ms, memory: 7500kb, points: 10, status: Accepted
> test 7: time: 40ms, memory: 8220kb, points: 10, status: Accepted
> test 8: time: 35ms, memory: 7924kb, points: 10, status: Accepted
> test 9: time: 36ms, memory: 8112kb, points: 10, status: Accepted
> test 10: time: 46ms, memory: 8252kb, points: 10, status: Accepted

B. 小埋学习图之环问题

时间:1s 空间:512M

题目描述

小埋最近在学习图相关知识,平时做的一些题目都是没有环的情况,现在小埋遇到了一个关于图的环的问题,

问题描述是有一个含 \(n\) 个顶点的双向图,每对顶点最多通过一条边连接,让小埋找到图中的最短的环的长度,

如果不存在环的话,就输出 -1

环是指以同一节点开始和结束,并且路径中的每条边仅使用一次。

题目输入

第一行是两个整数 \(n,m\)\(n\) 代表该图有 \(n\)个节点,\(m\) 的话代表有 \(m\) 条双向边。

题目输出

输出一个整数是该图中的最小环的长度。

样例1输入

7 7
1 2
2 3
3 1
4 5
5 6
6 7
7 4

样例1输出

3

样例2输入

3 2
1 2
2 3

样例2输出

-1

数据范围

\(2 \le n \le 1000\)\(1 \le m \le 1000\)\(1 \le u,v \le n\)\(u \ne v\)

不存在重复的边

点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;

int n, m, ans = 0x3f3f3f3f;
int vis[1005];
vector<int> v[1005];

void bfs(int x) {
    memset(vis, 0, sizeof vis);
    queue<int> q;
    q.push(x);
    q.push(0);
    while(!q.empty()) {
        int u, f;
        u = q.front(); q.pop();
        f = q.front(); q.pop();
        for(int i = 0; i < v[u].size(); i ++) {
            if(v[u][i] != f) {
                if(vis[v[u][i]] != 0 && vis[v[u][i]] + vis[u] + 1 != 2 && vis[v[u][i]] + vis[u] + 1 <= n)
                    ans = min(ans, vis[v[u][i]] + vis[u] + 1);
                else {
                    vis[v[u][i]] = vis[u] + 1;
                    q.push(v[u][i]);
                    q.push(u);
                }
            }
        }
    }
}

int main() {
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) {
        int fr, to;
        cin >> fr >> to;
        v[fr].push_back(to);
        v[to].push_back(fr);
    }
    for(int i = 1; i <= n; i ++) {
        //memset(vis, 0, sizeof vis);
        bfs(i);
    }
    if(ans == 0x3f3f3f3f) cout << "-1\n";
    else cout << ans << endl;
    return 0;
}
编译结果
compiled successfully
time: 92ms, memory: 3536kb, score: 100, status: Accepted
> test 1: time: 6ms, memory: 3340kb, points: 10, status: Accepted
> test 2: time: 2ms, memory: 3464kb, points: 10, status: Accepted
> test 3: time: 18ms, memory: 3448kb, points: 10, status: Accepted
> test 4: time: 8ms, memory: 3472kb, points: 10, status: Accepted
> test 5: time: 11ms, memory: 3424kb, points: 10, status: Accepted
> test 6: time: 0ms, memory: 3536kb, points: 10, status: Accepted
> test 7: time: 12ms, memory: 3432kb, points: 10, status: Accepted
> test 8: time: 7ms, memory: 3480kb, points: 10, status: Accepted
> test 9: time: 13ms, memory: 3384kb, points: 10, status: Accepted
> test 10: time: 15ms, memory: 3472kb, points: 10, status: Accepted

C. 小埋学习图之无法到达的点关系问题

时间:1s 空间:512M

题目描述

小埋最近在学习关于图相关的一些知识,现在小埋遇到了这样一个问题,给我们一个整数 \(n\)

表示一张无向图中有 \(n\) 个节点,编号为 \(1 \sim n\)。然后输入一个 \(m\),然后有 \(m\) 条双向边,每次输入两个整数

\(u,v\) 代表 \(u,v\) 之间有一条双向边,现在想要知道所有无法互相到达的不同的点对数目。

无法互相到达的意思是,\(a\) 点不能到达 \(b\) 点,\(b\) 不能到达 \(a\)点。

题目输入

输入一行有两个整数 \(n,m\)

以下 \(m\) 行,每行两个整数,\(u,v\) 两条边。

题目输出

输出一个整数,代表相互不能到达的点对数。

样例1输入

3 3
1 2
2 3
1 3

样例1输出

0

样例2输入

7 5
1 3
1 6
3 5
2 7
6 5

样例2输出

14

数据范围

\(1 \le n \le 100000\),\(1 \le m \le 50000\)

不会有重复边

样例二的图如下。

点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<string.h>
#include<map>
using namespace std;

long long n, m, num[100005], ans = 0, cnt = 0;
bool vis[100005];
vector<int> v[100005];

void dfs(int t, int x) {
    vis[x] = true;
    for(int i = 0; i < v[x].size(); i ++) {
        if(vis[v[x][i]]) continue;
        num[t]++;
        dfs(t, v[x][i]);
    }
    return;
}

int main() {
    cin >> n >> m;
    for(int i = 1; i <= m; i ++) {
        int fr, to;
        cin >> fr >> to;
        v[fr].push_back(to);
        v[to].push_back(fr);
    }
    for(int i = 1; i <= n; i ++) {
        if(!vis[i]) {
            num[cnt + 1] = 1;
            dfs(++cnt, i);
        }
    }
    for(int i = 1; i <= cnt; i ++) {
        ans += num[i] * (n - num[i]);
    }
    cout << ans / 2 << endl;
    return 0;
}
编译结果
compiled successfully
time: 239ms, memory: 8140kb, score: 100, status: Accepted
> test 1: time: 28ms, memory: 8008kb, points: 10, status: Accepted
> test 2: time: 18ms, memory: 7184kb, points: 10, status: Accepted
> test 3: time: 34ms, memory: 8140kb, points: 10, status: Accepted
> test 4: time: 35ms, memory: 8048kb, points: 10, status: Accepted
> test 5: time: 2ms, memory: 5788kb, points: 10, status: Accepted
> test 6: time: 19ms, memory: 6928kb, points: 10, status: Accepted
> test 7: time: 35ms, memory: 7500kb, points: 10, status: Accepted
> test 8: time: 17ms, memory: 7084kb, points: 10, status: Accepted
> test 9: time: 22ms, memory: 7408kb, points: 10, status: Accepted
> test 10: time: 29ms, memory: 8052kb, points: 10, status: Accepted

错题整理

程序阅读题

1 #include<bits/stdc++.h>
2 using namespace std;
3 int a[100005],b[100005],c[100005];
4 int main() {
5	int n,i,j,m,k=0,sign=0;
6	cin>>n;
7	for(i=0; i<n; ++i) {
8		cin>>a[i];
9		c[i]=a[i];
10	}
11	sort(c,c+n);
12	for(j=0; j<n-1; ++j) {
13		if(a[j]==c[n-1]) {
14			k=n-1-j;
15		}
16		if(a[j+1]<a[j])
17			sign=1;
18	}
19	if(sign==0) {
20		cout<<0<<endl;
21		return 0;
22	}
23	for(i=0; i<n; ++i)
24		b[(i+k)%n]=a[i];
25	for(i=0; i<n; ++i) {
26		if(b[i]!=c[i]) {
27			cout<<-1<<endl;
28			return 0;
29		}
30	}
31	cout<<k<<endl;
32	return 0;
33 }
  1. \(12\)\(j<n-1\) 改为 \(j<n\),结果不会有影响。 \(T\)

题解

改了之后,唯一有影响的就是单调递增序列,\(sign \ne 0\) 了,但由于这种序列不需要位移,最后答案仍然为 \(0\)

  1. \(a\) 数组元素大小单调时,输出结果一定不为 \(-1\)\(F\)
01 #include < bits/stdc++.h >
02 using namespace std;
03 const int maxn = 500000, INF = 0x3f3f3f3f;
04 int L[maxn / 2 + 2], R[maxn / 2 + 2];
05 void unknown(int a[], int n, int left, int mid, int right)
06 {
07     int n1 = mid - left, n2 = right - mid;
08     for (int i = 0; i < n1; i++)
09         L[i] = a[left + i];
10     for (int i = 0; i < n2; i++)
11         R[i] = a[mid + i];
12     L[n1] = R[n2] = INF;
13     int i = 0, j = 0;
14     for (int k = left; k < right; k++)
15     {
16         if (L[i] < = R[j])
17             a[k] = L[i++];
18         else
19             a[k] = R[j++];
20     }
21 }
22 void unknownsort(int a[], int n, int left, int right)
23 {
24     if (left + 1 < right)
25     {
26         int mid = (left + right) / 2;
27         unknownsort(a, n, left, mid);
28         unknownsort(a, n, mid, right);
29         unknown(a, n, left, mid, right);
30 	    }
31 }
32 int main()
33 {
34     int a[maxn], n;
35     cin >> n;
36     for (int i = 0; i < n; i++)
37     cin >> a[i];
38     unknownsort(a, n, 0, n);
39     for (int i = 0; i < n; i++)
40     {
41         if (i)
42             cout < < "  ";
43         cout < < a[i];
44     }
45     cout < < endl;
46     return 0;
47 }
  1. 此类排序方法是高效的但是不稳定。 \(F\)

大整数开方: 输入一个正整数 \(n(1 \le n \le 10^{100})\),试用二分法计算它的平方根的整数部分。

#include<iostream>
#include<string>
using namespace std;
const int SIZE=200;
struct hugeint{
    int len,num[SIZE];
};
//其中len表示大整数的位数;num[1]表示个位,num[2]表示十位,以此类推
hugeint times(hugeint a,hugeint b)
// 计算大整数a和b的乘积
{
    int i,j;
    hugeint ans;
    memset(ans.num,0,sizeof(ans.num));
    for(i=1;i<=a.len;i++)
       for(j=1;j<=b.len;j++)
                  ①      +=a.num[i]*b.num[j];  
    for(i=1;i<=a.len+b.len;i++){
        ans.num[i+1]+=ans.num[i]/10;
                 ②         ; 
    }
    if(ans.num[a.len+b.len]>0)
        ans.len=a.len+b.len;
    else
        ans.len=a.len+b.len-1;
    return ans;
}
hugeint add(hugeint a,hugeint b)
//计算大整数a和b 的和
{
    int i;
    hugeint ans;
    memset(ans.num,0,sizeof(ans.num));
    if(a.len>b.len)
        ans.len=a.len;
    else
        ans.len=b.len;
    for(i=1;i<=ans.len;i++){
        ans.num[i]+=         ③       ; 
        ans.num[i+1]+= ans.num[i]/10;
        ans.num[i]%=10;
    }
    if(ans.num[ans.len+1]>0)
        ans.len++;
    return ans;
}
hugeint average(hugeint a,hugeint b)
//计算大整数a和b的平均数的整数部分
{
    int i;
    hugeint ans;
    ans=add(a,b);
    for(i=ans.len;i>=2;i--){
        ans.num[i-1]+=(     ④      )*10; 
        ans.num[i]/=2;
    }
    ans.num[1]/=2;
    if(ans.num[ans.len]==0)
        ans.len--;
    return ans;
}
hugeint plustwo(hugeint a)
// 计算大整数a加2之后的结果
{
    int i;
    hugeint ans;
    ans=a;
    ans.num[1]+=2;
    i=1;
    while( (i<=ans.len)&&(ans.num[i]>=10) ){
        ans.num[i+1]+=ans.num[i]/10;
        ans.num[i]%=10;
        i++;
    }
    if(ans.num[ans.len+1]>0)
              ⑤    ; 
    return ans;
}
bool over(hugeint a,hugeint b)
// 若大整数a>b则返回true,否则返回false
{
    int i;
    if(      ⑥     )  
        return false;
    if( a.len>b.len )
        return true;
    for(i=a.len;i>=1;i--){
        if(a.num[i]<b.num[i])
           return false;
        if(a.num[i]>b.num[i])
           return true;
    }
    return false;
}
int main()
{
    string s;
    int i;
    hugeint target,left,middle,right;
    cin>>s;
    memset(target.num,0,sizeof(target.num));
    target.len=s.length();
    for(i=1;i<=target.len;i++)
        target.num[i]=s[target.len-i]-      ⑦    ;
    memset(left.num,0,sizeof(left.num));
    left.len=1;
    left.num[1]=1;
    right=target;
    do{
        middle=average(left,right);
        if(over(       ⑧        ))
            right=middle;
        else
            left=middle;
    }while(!over(plustwo(left),right) );
    for(i=left.len;i>=1;i--)
       cout<<left.num[i];
    return 0;
}
  1. 第一空填 ()
    A. ans.num[j - 1]
    B. ans.num[i + j - 1]
    C. ans.num[i + j]
    D. ans.num[i - j - 1]
01 #include <iostream>
02 using namespace std;
03 const int NUM = 5;
04 int r(int n)
05 {
06     int i;
07     if (n <= NUM)
08         return n;
09     for (i = 1; i <= NUM; i++)
10         if (r(n - i) < 0)
11             return i;
12     return -1;
13 }
14 int main()
15 {
16     int n;
17     cin >> n;
18     cout << r(n) << endl;
19     return 0;
20 }
  1. 输入“25”,输出为()。
    A. 1
    B. 2
    C. 3
    D. 4
#include <stdio.h>
#include <string.h>
void makeNext(char P[], int Next[]) {
    int q, k;
    int m = strlen(P);
    Next[0] = 0;
    for (q = 1, k = 0; q < m; ++q) {
        while (k > 0 && P[q] != P[k]) k = Next[k - 1];
        if (P[q] == P[k]) { k++; }
        Next[q] = k;
    }
}
int main() {
    char s[1005];
    int Next[1005] = {0}, i;
    scanf("%s", s);
    makeNext(s, Next);
    for (i = 0; i < strlen(s); i++) {
        if (Next[i] > 0) printf("%d ", Next[i]);
    }
    return 0;
}
  1. 程序使用了 \(KMP\) 算法。 \(T\)
  1. 若输入 \(CDCABECADDCD\),则输出(  )个元素。
    A. \(3\)
    B. \(4\)
    C. \(5\)
    D. \(6\)
  1. 若输出 \(CDCABECADDCDCABDDBDC\),则输出(  ) 个元素。
    A. \(5\)
    B. \(6\)
    C. \(7\)
    D. \(8\)

过河问题: 在一个月黑风高的夜晚,有一群人在河的右岸,想通过唯一的一根独木桥走到河的左岸。在这伸手不见五指的黑夜里,过桥时必须借助灯光来照明,很不幸的是,他 们只有一盏灯。另外,独木桥上最多承受两个人同时经过,否则将会坍塌。每个人单独过桥 都需要一定的时间,不同的人需要的时间可能不同。两个人一起过桥时,由于只有一盏灯, 所以需要的时间是较慢的那个人单独过桥时所花的时间。现输入 \(n(2 \le n < 100)\) 和这 \(n\) 个 人单独过桥时需要的时间,请计算总共最少需要多少时间,他们才能全部到达河的左岸。 例如,有 \(3\) 个人甲、乙、丙,他们单独过桥的时间分别为 \(1、2、4\),则总共最少需要 的时间为 \(7\)。具体方法是:甲、乙一起过桥到河的左岸,甲单独回到河的右岸将灯带回,然 后甲、丙再一起过桥到河的左岸,总时间为 \(2+1+4=7\)

01 #include <iostream>
02 using namespace std;
03 const int SIZE = 100;
04 const int INFINITY = 10000;
05 const bool LEFT = true;
06 const bool RIGHT = false;
07 const bool LEFT_TO_RIGHT = true;
08 const bool RIGHT_TO_LEFT = false;
09 int n, hour[SIZE];
10 bool pos[SIZE];
11 int max(int a, int b)
12 {
13     if (a > b)
14         return a;
15     else return b;
16 }
17 int go(bool stage)
18 {
19     int i, j, num, tmp, ans;
20     if (stage == RIGHT_TO_LEFT)
21     {
22         num = 0;
23         ans = 0;
24         for (i = 1; i <= n; i++)
25             if (pos[i] == RIGHT)
26             {
27                 num++;
28                 if (hour[i] > ans)
29                     ans = hour[i];
30             }
31         if ((1)) 
32             return ans;
33         ans = INFINITY;
34         for (i = 1; i <= n - 1; i++)
35             if (pos[i] == RIGHT)
36                 for (j = i + 1; j <= n; j++)
37                     if (pos[j] == RIGHT)
38                     {
39                         pos[i] = LEFT;
40                         pos[j] = LEFT;
41                         tmp = max(hour[i], hour[j]) + (2) ;
42                         if (tmp < ans)
43                             ans = tmp;
44                         pos[i] = RIGHT;
45                         pos[j] = RIGHT;
46                     }
47         return ans;
48     }
49     if (stage == LEFT_TO_RIGHT)
50     {
51         ans = INFINITY;
52         for (i = 1; i <= n; i++)
53             if ( (3) )
54             {
55                 pos[i] = RIGHT;
56                 tmp = (4) ;
57                 if (tmp < ans)
58                     ans = tmp;
59                 (5) ;
60             }
61         return ans;
62     }
63     return 0;
64 }
65 int main()
66 {
67     int i;
68     cin >> n;
69     for (i = 1; i <= n; i++)
70     {
71         cin >> hour[i];
72         pos[i] = RIGHT;
73     }
74     cout << go(RIGHT_TO_LEFT) << endl;
75     return 0;
76 }
  1. (2)处应填()。
    A. \(go(RIGHT_TO_LEFT)\)
    B. \(go(LEFT_TO_RIGHT)\)
    C. \(go(LEFT)\)
    D. \(go(RIGHT)\)
  1. (5)处应填()。
    A. \(hour[i]=LEFT\)
    B. \(hour[i]=RIGHT\)
    C. \(pos[i]=LEFT\)
    D. \(pos[i]=RIGHT\)
1 #include<iostream>
2 using namespace std;
3 int f(int n,int k){
4	if (n == k || k == 0) return 1;
5	else return f(n - 1, k) + f(n - 1, k - 1);
6  }
7  int main() {
8  int n,k,m;
9  cin >> n >> k;
10 cout << f(n,k);
11 return 0;
12 }
  1. 程序的时间复杂度为多项式级别。 \(F\)
1.#include <cstdio>
2.#define N 1005
3.
4.using namespace std;
5.int num[N];
6.
7.int main(){
8.  int al=1,n,x;
9.  scanf("%d",&n);
10.  num[1]=1;
11.  for(int i=1;i<=n;++i){
12.    x=0;
13.    for(int j=1;j<=al;++j){
14.      num[j]=num[j]*5+x;
15.      x=num[j]/10;
16.      num[j]%=10;
17.    }
18.    if(x>0) num[++al]=x;
19.  }
20.  printf("0.");
21.  for(int i=al;i<n;++i){
22.    putchar('0');
23.  }
24.  for(int i=al;i>=1;i--){
25.    printf("%d",num[i]);
26.  }
27.  putchar('\n');
28.  return 0;
29.}
  1. 此程序的时间复杂度是( )
    A. \(O(n)\)
    B. \(O(n^2)\)
    C. \(O(n^3)\)
    D. \(O(n \times log_n)\)

字符串合并: 给你两个字符串 \(a,b\),是否能不改变 \(a,b\) 字符串原有顺序合成 \(c\)

例如:
输入:lab tree latrbee
输出:Yes
输入:lab tree laterbe
输出:No

#include <stdio.h>
#include <string.h>
#define Max 505
char a[Max], b[Max], c[Max];
int flag = 0;
int vis[Max][Max];
void dfs(int i, int j, int cnt) {
    if ((  ① )) {  //  c已经完全匹配完了;
        (  ② );
        return;
    }
    if (a[i] != c[cnt] && b[j] != c[cnt]) return;  //  剪枝
    if (vis[i][j]) return;                         //  剪枝
    (  ③ );
    if ((  ④ )) dfs(i + 1, j, cnt + 1);
    if (flag) return;
    if (b[j] == c[cnt]) (  ⑤ );
}
int main() {
    flag = 0;
    memset(vis, 0, sizeof(vis));
    scanf("%s%s%s", a, b, c);
    dfs(0, 0, 0);
    if (flag)
        printf("Yes\n");
    else
        printf("No\n");
    return 0;
}
  1. ① 处应填(  )。
    A. \(cnt == strlen(c)\)
    B. \(cnt == strlen(c + 1)\)
    C. \(cnt == c.length()\)
    D. \(cnt == c.length() - 1\)

选填题

  1. 设某强连通图中有 \(n\) 个顶点,则该强连通图中至少有( )条边
    A. \(n(n-1)\)
    B. \(n+1\)
    C. \(n\)
    D. \(n(n+1)\)
  1. 假设线性表的长度为 \(n\),则在最坏情况下,冒泡排序需要的比较次数为
    A. \(log_2n\)
    B. \(n^2\)
    C. \(O(n^{1.5})\)
    D. \(n(n−1)/2\)
  1. 如果用一个字节来表示整数,最高位用作符号位,其他位表示数值。例如: \(0000001\) 表示 \(+1\)\(1000001\) 表示 \(-1\),试问这样表示法的整数A的范围应该是()
    A. \(-127 \le A \le 127\)
    B. \(−128 \le A \le 128\)
    C. \(−127 \le A \le 128\)
    D. \(−128 \le A \le 127\)
posted @ 2023-07-28 14:01  So_noSlack  阅读(310)  评论(0编辑  收藏  举报