CSDN竞赛43期题解

总结

有二十来期没有写题解了,基本都是重复的题目,奖励也是重复的,就忽略了n条奖惩公告了。这次竞赛也都是重复的题目,往期基本也都写过题解,所以内容不太重要。这次比赛赛后也看不见考试报告,代码为赛后重写。

两点建议:重复的题目如果有点难度,第一次考的时候往往满分寥寥无几,再次考短时间内AC的数不胜数,所以基本失去了竞赛的意义,还不如在网上题库里改下简单题目背景出题呢;另外竞赛4~10名的奖励往往都是一样的,参加个十几期比赛,拿个十几个帆布包放家里不太合适吧,不如整点积分制,攒够几次4-10的排名,换本需要的书看看有意义。这期的2-3名奖励应该是图书盲盒,希望别是构建之法和编程之美了,这两本早早的拿过了。

最后再吐槽下44期的竞赛,出个客观题为了增加书的读者也没啥,填空题问论文名字感觉是想把分数送给买过书的人,毕竟百度到的其它论文名称都不得分,让编程题做的比较快的同学因为这个排名靠后不太应该。

题目列表

1.判断胜负

题目描述

已知两个字符串A,B。
连续进行读入n次。
每次读入的字符串都为A|B。
输出读入次数最多的字符串。

输入描述:

第一行输入整数n.(1<=n<=100)。
以下n行读入n个字符串。

输出描述:

输出读入次数最多的字符串,如果两个字符串读入次数相同输出,”dogfall”。

输入样例:

3
A
ASDA
A

输出样例:

A

分析

使用map对字符串计数,最后遍历下map,出现次数超过 n / 2 n / 2 n/2的直接输出,如果两个字符串出现的次数都不超过 n / 2 n / 2 n/2,输出dogfall。

代码

#include 
#include 
using namespace std;
map<string,int> m;
int main() {
    int n;
    cin>>n;
    string s;
    for(int i = 0;i < n;i++) {
        cin>>s;
        m[s]++;
    }
    for(auto t : m) {
        if (t.second > n / 2) {
            cout<<t.first<<endl;
            return 0;
        }
    }
    cout<<"dogfall"<<endl;
    return 0;
}

2.小豚鼠搬家

题目描述

小艺酱买了一排排格子的小房子n*m,她想让k只小豚鼠每只小豚鼠都有自己的房子。 但是为了不浪费空间,她想要小房子的最外圈尽量每行每列都有一只小豚鼠居住(小豚鼠也可以住在中间的格子,只需保证房子最外围的行和列至少住一只豚鼠即可,无需每行每列都有豚鼠)。 小艺酱想知道自己有多少种方案安排小豚鼠。

输入描述:

输入整数n,m,k。(1<=n,m<=20,0<=k<=n*m)

输出描述:

输出方案数,答案对1e9+7取模。

输入样例:

3 3 2

输出样例:

2

分析

本题给的数据范围很小,所以可以直接暴搜,甚至不用优化。要注意的是小豚鼠可以住在中间的格子,不是非要住在边界格子。而且并不是每行每列都需要有小豚鼠居住,只要最外围的行和列至少住了一只就可以了。dfs时可以使用状态压缩表示和判断状态,具体实现见代码。

代码

#include 
#include 
#include 
#include 
using namespace std;
int a[30],b[30];
int ans = 0,cnt = 0;
int n,m,k;
void dfs(int u,int c,int s,int t) {
	if(c == k) {
		if((s & 1) && (t & 1)) {
			if((s >> (n - 1) & 1) && (t >> (m-1) & 1)) ans++;
			return;
		}
	}
	if(u >= cnt) return;
    //放小豚鼠
	dfs(u+1,c+1,s | (1 << a[u]),t | (1 << b[u]));
    //不放小豚鼠
	dfs(u+1,c,s,t);
}
int main() {
	cin>>n>>m>>k;
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			a[cnt] = i;
			b[cnt++] = j;
		}
	}
	dfs(0, 0, 0 , 0);
	cout<<ans<<endl;
	return 0;
}

3.醉酒的狱卒

题目描述

某监狱有一个由n个牢房组成的大厅,每个牢房紧挨着。每个牢房里都有一个囚犯,每个牢房都是锁着的。

一天晚上,狱卒感到无聊,决定玩一个游戏。在第一轮,他喝了一杯威士忌,然后跑下大厅,打开每个牢房的锁。在第二轮比赛中,他喝了一杯威士忌,然后跑下大厅,锁上每隔一个的牢房的锁(牢房2、4、6…)。在第三轮比赛中,他喝了一杯威士忌,然后跑下大厅。他每隔三个牢房(第3、6、9号牢房)就去一次。如果牢房被锁上了,他就把它打开;如果牢房门打开了,他就锁上牢房。他重复n轮,喝最后一杯,然后昏倒。
一些囚犯(可能为零号)意识到他们的牢房被解锁且狱卒丧失了行动能力。他们就可以立即逃跑。现在根据牢房数量,确定有多少囚犯越狱。

输入描述:

第一行输入包含一个正整数t。表示有t行数据,下面每一行都包含一个介于5和100之间(含5和100)的整数,即轮数n

输出描述:

对于每一行,必须打印出监狱有n个牢房时越狱的囚犯人数

输入样例:

2
5
100

输出样例:

2
10

分析

n个牢房,每个数的倍数都会被光顾,因此,只要一个牢房的编号有奇数个因子,那么囚犯就可以逃走。可以直接模拟实现。

当然,如果 a a a n n n的因子,那么 n / a n/a n/a必然也是 n n n的因子,如果 a   ! = n / a a\ !=n/a a !=n/a,那么 n n n就多了两个因子,否则多了一个因子。因此只要 n n n是完全平方数,那么这个牢房最后是打开的。问题就转化成了 n n n以内完全平方数的个数,结果是 n \sqrt{n} n 个。

代码

#include 
#include 
#include 
#include 
#include 
using namespace std;
int main() {
	int t;
	std::vector<std::vector<std::string>> vec;
	std::cin>>t;
	while(t--) {
		int n;
		cin>>n;
		cout<<sqrt(n)<<endl;
	}
	return 0;
}

4.会议安排

题目描述

开会了!作为一个集体,开会的时候桌子当然是需要和老大相邻的!(老大可能坐在桌子上边)
小艺被分配到排桌椅的活,可是小艺的力气都用在吃上了,怎么可能搬动这些桌椅呢。
她决定用现有的布局当作是会议座位安排。
每个桌子分配一个人。相邻桌子不同的桌子颜色不同。
小艺想知道选择某个桌子之后老大身边能围多少人?

输入描述:

第一行输入2个整数n,m,一个字符c。(1<=n,m<=100)分别表示空间大小和老大指定的桌椅颜色号。
以下n行每行m个字符。’.’代表空地,其他字符表示桌椅。连接在一个且相同的字符表示一个桌子。

输出描述:

输出围着老大的人数。

输入样例:

3 4 R
G.B.
BRRA
TTT.

输出样例:

4

分析

这题的用例比较水,本来是想表达相邻的相同字符表示一个桌子,不相邻的相同字符表示不同桌子的,但是代码不需要判断是否相邻,将老大周围字符一股脑的放入set,最后输出set的size就可以通过了。

代码

#include 
#include 
using namespace std;
set<char> s;
const int N = 105;
char g[N][N];
int n,m;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
int main() {
    int n,m;
    cin>>n>>m;
    char c;
    cin>>c;
    for(int i = 0;i < n;i++)	cin>>g[i];
    for(int i = 0;i < n;i++) {
        for(int j = 0;j < m;j++) {
            if (g[i][j] == c) {
                for(int k = 0;k < 4;k++) {
                    int x = i + dx[k], y = j + dy[k];
                    if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]!=c&&g[x][y]!='.') {
                        s.insert(g[x][y]);
                    }
                }
            }
        }
    }
    cout<<s.size()<<endl;
    return 0;
}

你可能感兴趣的:(其它,dfs)