【题目描述】
把M�个同样的苹果放在N�个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K�表示)
5,1,1
和1,5,1
是同一种分法。【输入】
第一行是测试数据的数目t�(0≤t≤200≤�≤20)。以下每行均包含二个整数M�和N�,以空格分开。1≤M,N≤101≤�,�≤10。
【输出】
对输入的每组数据M�和N�,用一行输出相应的K。
【输入样例】
1 7 3
【输出样例】
8
#include
using namespace std;
const int N = 1e5 + 10;
int t, n, m;
int cnt[N];
int ans = 0;
//搜索状态为s, s代表当前已经搜索的答案的累加和
void dfs(int s, int depth) {
//5.终止条件
if (s > n) return;
if (depth <= m + 1 && s == n) {//n选r问题更改条件处
ans++;
return;
}
//1.枚举方案(枚举的时候直接排列变组合)
for (int i = cnt[depth - 1]; i <= n; i++) {
//2.本题需要重复搜索,则不需要加标记,故第二步略
//3.搜索
cnt[depth] = i;
dfs(s + i, depth + 1);
//4.回溯,若s作为状态传入dfs,则回溯的时候,s自动还原
}
}
int main() {
cin >> t;
while (t--) {
cin >> n >> m;
cnt[0] = 1;
ans = 0;//多组数据,相关状态初始化
dfs(0, 1);//初始状态
cout << ans << endl;
}
return 0;
}
【题目描述】
给定n个正整数,将它们分组,使得每组中任意两个数互质。至少要分成多少个组?
【输入】
第一行是一个正整数n。1 ≤ n ≤ 10。
第二行是n个不大于10000的正整数。
【输出】
一个正整数,即最少需要的组数。
【输入样例】
6 14 20 33 117 143 175
【输出样例】
3
本题需掌握的知识点:
1.互质的两个数a,b满足gcd(a,b)=1
2.若a,b,c互质,则c与a*b互质,反之也成立
#include
using namespace std;
const int N = 1e4 + 10;
int n, a[N];
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {//清零的位置不需要考虑
for (int j = i + 1; j <= n; j++) {
if (a[i] != 0 && gcd(a[i], a[j]) == 1) {
a[i] *= a[j];
a[j] = 0;
}
}
}
int cnt = 0;
for (int i = 1; i <= n; i++) if (a[i] != 0) cnt++;
cout << cnt << endl;
return 0;
}
【题目描述】
有两堆石子,两个人轮流去取。每次取的时候,只能从较多的那堆石子里取,并且取的数目必须是较少的那堆石子数目的整数倍,最后谁能够把一堆石子取空谁就算赢。
比如初始的时候两堆石子的数目是25和7。
25 7 --> 11 7 --> 4 7 --> 4 3 --> 1 3 --> 1 0 选手1取 选手2取 选手1取 选手2取 选手1取 最后选手1(先取的)获胜,在取的过程中选手2都只有唯一的一种取法。
给定初始时石子的数目,如果两个人都采取最优策略,请问先手能否获胜。
【输入】
输入包含多数数据。每组数据一行,包含两个正整数a和b,表示初始时石子的数目。
输入以两个0表示结束。
【输出】
如果先手胜,输出"win",否则输出"lose"。
【输入样例】
34 12 15 24 0 0
【输出样例】
win lose
【提示】
假设石子数目为(a,b)且a >= b,如果[a/b] >= 2则先手必胜,如果[a/b]<2,那么先手只有唯一的一种取法。[a/b]表示a除以b取整后的值。
#include
using namespace std;
//搜索状态为a,b代表两堆石子的数量
bool dfs(int a, int b) {
if (a < b) swap(a, b);
if (a % b == 0) return true;//某一方赢了
//枚举b的倍数i,但是要保证i*b不超过a
for (int i = a / b; i >= 1; i--)
//枚举所有取法,但凡能找到一种让对方输的情况,那么当前选手都会赢
if (dfs(a - i * b, b) == false) return true;
return false;//枚举所有取法,都没找到一种让对方输的情况,那么当前选手输
}
//选手1执行dfs(7,3)=true dfs(1,3)=true dfs(4,3)=false
//选手2执行dfs(4,3)=false dfs(1,3)=true
//选手1执行dfs(1,3)赢了
//选手2执行dfs(1,3)赢了
int main() {
int a, b;
while (cin >> a >> b && a && b) {
if (dfs(a, b) == true) cout << "win" << endl;
else cout << "lose" << endl;
}
return 0;
}
信息学奥赛一本通(C++版)在线评测系统
#include
using namespace std;
const int N = 1e2 + 10;
int a[N][N];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
cout << a[j][i] << " ";
cout << endl;
}
return 0;
}
1127:图像旋转 |
#include
using namespace std;
const int N = 1e2 + 10;
int a[N][N];
int n, m;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> a[i][j];
for (int j = 1; j <= m; ++j)//遍历矩阵b,m行n列
{
for (int i = n; i >= 1; --i)
cout << a[i][j] << ' ';
cout << endl;
}
return 0;
}
#include
#include
using namespace std;
const int N = 1e2 + 10;
int a[N][N],b[N][N];
int n, m;
int s;//上下左右以及该点的平均值
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> a[i][j];
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if (!(i == 1 || i == n || j == 1 || j == m))
{
s = a[i][j] + a[i - 1][j] + a[i + 1][j] + a[i][j - 1] + a[i][j + 1];
s = round((double)s / 5);
b[i][j] = s;
}
else
b[i][j] = a[i][j];
}
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
cout << b[i][j] << " ";
cout << endl;
}
return 0;
}
#include
#include
using namespace std;
const int N = 1e2 + 10;
int a[N][N],b[N][N];
int n, x,y;
int main()
{
cin >> n >> x>>y;
for (int j = 1; j <= n; ++j)
printf("(%d,%d) ", x, j);
putchar('\n');
for (int i = 1; i <= n; ++i)
printf("(%d,%d) ", i, y);
putchar('\n');
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (i - j == x - y)
printf("(%d,%d) ", i, j);
putchar('\n');
for (int i = n; i >= 1; --i)
for (int j = 1; j <= n; ++j)
if (i + j == x + y)
printf("(%d,%d) ", i, j);
putchar('\n');
return 0;
}
#include
#include
using namespace std;
string s;
char a, b;
int main()
{
getline(cin, s);
cin >>a>>b;
for (auto &c : s)
if (c == a)
c =b;
cout << s;
return 0;
}