Bootstrap

历年CSP-J初赛真题解析 | 2017年CSP-J初赛阅读程序(23-26)

学习C++从娃娃抓起!记录下CSP-J备考学习过程中的题目,记录每一个瞬间。

附上汇总贴:历年CSP-J初赛真题解析 | 汇总_热爱编程的通信人的博客-CSDN博客


#include <iostream>
using namespace std;
int main()
{
	int t[256];
	string s;
	int i;
	cin >> s;
	for (i=0; i<256; i++)
		t[i] = 0;
	for (i=0; i<s.length(); i++)
		t[s[i]]++;
	for (i=0; i<s.length(); i++)
		if (t[s[i]]==1)
		{
			cout << s[i] << endl;
			return 0;
		}
	cout << "no" << endl;
	return 0;
}

第23题

输入:xyzxyw

输出:( )

【答案】:z

【解析】

程序的功能是输出第一个只出现1次的字母7845690-23978-6=

#include <iostream>
using namespace std;

int g(int m, int n, int x)
{
	int ans = 0;
	int i;
	if (n==1)
		return 1;
	for (i=x; i<=m/n; i++) 
		ans += g(m-i, n-1, i);
	return ans;
}

int main()
{
	int t, m, n;
	cin >> m >> n;
	cout << g(m, n, 0) << endl;
	return 0;
}

第24题

输入:7 3

输出:( )

【答案】:8

【解析】

g(7,3,0)=g(7,2,0)+g(6,2,1)+g(5,2,2)

g(7,2,0)=g(7,1,0)+g(6,1,1)+g(5,1,2)+g(4,1,3)=4

g(6,2,1)=g(5,1,1)+g(4,1,2)+g(3,1,3)=3

g(5,2,2)=g(3,1,2)=1

所以g(7,3,0)=8

求排列组合的题,m+x==m的方案数

#include <iostream>
using namespace std;

int main()
{
	string ch;
	int a[200];
	int b[200];
	int n, i, t, res;
	cin >> ch;
	n = ch.length();
	for (i=0; i<200; i++)
		b[i] = 0;
	for (i=1; i<=n; i++)
	{
		a[i] = ch[i-1] - '0';
		b[i] = b[i-1] + a[i];
	}
	res = b[n];
	t = 0;
	for (i=n; i>0; i--)
	{
		if (a[i]==0)
			t++;
		if (b[i-1]+t<res)
			res = b[i-1] + t;
	}
	cout << res << endl;
	return 0;
}

第25题

输入:1001101011001101101011110001

输出:( )

【答案】:11

【解析】

012345678910111213141516171819202122232425262728
ch1001101011001101101011110001
a[ ]01001101011001101101011110001
b[ ]01112334456667889101011111213141515151516
t
1212111010109988876665554433333210
res1112131415

b数组是在算从头到i的“1”的个数(前缀和),res为a数组中1的个数,t是从i到尾的“0”的个数(后缀和)。

程序的目的是将字符串劈成两半,前一半统计1的个数,后一半统计0的个数,计算什么时候得到的两者的个数最小。

#include <iostream>
using namespace std;
int main()
{
	int n, m;
	cin >> n >> m;
	int x=1;
	int y=1;
	int dx=1;
	int dy=1;
	int cnt = 0;
	while (cnt != 2)
	{
		cnt = 0;
		x = x + dx;
		y = y + dy;
		if (x==1 || x == n) 
		{
			++cnt;
			dx = -dx;
		}
		if (y==1 || y==m)
		{
			++cnt;
			dy = -dy;
		}
	}
	cout << x << " " << y << endl;
	return 0;
}

第26题

输入1:4 3

输出1:( )

输入2:2017 1014

输出2:( )

【答案】:1 3 和2017 1

【解析】

xydxdycnt
11110
22110
331-10/1
42-1-10/1
31-110/1
22-110
131-10/1/2

两个if语句都成立,才能结束while循环。(n-1)和(m-1)的最小公倍数。2017和2014的最小公倍数是2016 * 1013,即x走1013次,y走2016次,则1013为奇数,所以x到了2017,2016为偶数,所以y到了1

;