学习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
【解析】
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ch | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | |
a[ ] | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
b[ ] | 0 | 1 | 1 | 1 | 2 | 3 | 3 | 4 | 4 | 5 | 6 | 6 | 6 | 7 | 8 | 8 | 9 | 10 | 10 | 11 | 11 | 12 | 13 | 14 | 15 | 15 | 15 | 15 | 16 |
t | 12 | 12 | 11 | 10 | 10 | 10 | 9 | 9 | 8 | 8 | 8 | 7 | 6 | 6 | 6 | 5 | 5 | 5 | 4 | 4 | 3 | 3 | 3 | 3 | 3 | 2 | 1 | 0 | |
res | 11 | 12 | 13 | 14 | 15 |
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
【解析】
x | y | dx | dy | cnt |
---|---|---|---|---|
1 | 1 | 1 | 1 | 0 |
2 | 2 | 1 | 1 | 0 |
3 | 3 | 1 | -1 | 0/1 |
4 | 2 | -1 | -1 | 0/1 |
3 | 1 | -1 | 1 | 0/1 |
2 | 2 | -1 | 1 | 0 |
1 | 3 | 1 | -1 | 0/1/2 |
两个if语句都成立,才能结束while循环。(n-1)和(m-1)的最小公倍数。2017和2014的最小公倍数是2016 * 1013,即x走1013次,y走2016次,则1013为奇数,所以x到了2017,2016为偶数,所以y到了1