2022-01-18每日刷题打卡

一、信息学OJ  1317:【例5.2】组合的输出

【题目描述】

排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。

现要求你用递归的方法输出所有组合。

例如n=5,r=3,所有组合为:

1 2 3   1 2 4   1 2 5   1 3 4   1 3 5   1 4 5   2 3 4   2 3 5   2 4 5   3 4 5

【输入】

一行两个自然数n、r(1<n<21,1≤r≤n)。

【输出】

所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。

【输入样例】

5 3

【输出样例】

  1  2  3
  1  2  4
  1  2  5
  1  3  4
  1  3  5
  1  4  5
  2  3  4
  2  3  5
  2  4  5
  3  4  5

(2)代码实现

        

复制代码到粘帖板
#include<bits/stdc++.h>
using namespace std;
int n,r;
int vis[30]={0};
int a[30];
void print()
{
    for(int i=1;i<=r;i++)
        cout<<"  "<<a[i];
    cout<<endl;
}
void searchh(int step)
{
    for(int i=a[step-1];i<=n;i++)
    {
        if(!vis[i])
        {
            vis[i]=1;
            a[step]=i;
            if(step==r) print();
            else searchh(step+1);
            vis[i]=0;
        }
    }
}
int main()
{
    cin>>n>>r;
    a[0]=1;
    searchh(1);
    return 0;
}

 二、信息学OJ 1318:【例5.3】自然数的拆分

【题目描述】

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。

当n=7共14种拆分方法:

7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
total=14

【输入】

输入n。

【输出】

按字典序输出具体的方案。

【输入样例】

7

【输出样例】

7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4

(2)代码实现

        

#include <bits/stdc++.h>
using namespace std;
int a[100],sum1=0,n;
void fun(int m,int sum) 
{
	if(sum==n)
	{
		sum1++;
		cout<<n<<"=";
		for(int i=1;i<m;i++)
		{
			cout<<a[i];
			if(i!=m-1)
			{
				cout<<"+"; 
			}
		}
		cout<<endl;
	}
	else
	{
		for(int i=a[m-1];i<n;i++)
		{
			if(sum+i>n)
				break;
			else
			{
				a[m]=i;
				fun(m+1,sum+i);
				a[m]=0; 
			}
		}
	}
}
int main()
{
	cin>>n;
	a[0]=1;
	fun(1,0);
	return 0;
}

三、信息学OJ 1219:马走日

【题目描述】

马在中国象棋以日字形规则移动。

请编写一段程序,给定n×m大小的棋盘,以及马的初始位置(x,y),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

【输入】

第一行为整数T(T < 10),表示测试数据组数。

每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标n,m,x,y。(0≤x≤n-1,0≤y≤m-1, m < 10, n < 10)。

【输出】

每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0为无法遍历一次。

【输入样例】

1
5 4 0 0

【输出样例】

32

 (2)代码实现

        

复制代码到粘帖板
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define N 10
using namespace std;
int n,m;
int x0,y0;
char maps[N][N];
int vis[N][N];
int dir[8][2]={{-2,1},{-2,-1},{-1,2},{-1,-2},{2,1},{2,-1},{1,2},{1,-2}};
int cnt;
void dfs(int x,int y,int step)
{
    if(step==n*m)
    {
        cnt++;
        return;
    }
    for(int i=0;i<8;i++)
    {
        int nx=x+dir[i][0];
        int ny=y+dir[i][1];
        if(nx>=0&&ny>=0&&nx<n&&ny<m&&vis[nx][ny]==0)
        {
            vis[nx][ny]=1;
            dfs(nx,ny,step+1);
            vis[nx][ny]=0;
        }
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cnt=0;
        memset(vis,0,sizeof(vis));
 
        cin>>n>>m;
        cin>>x0>>y0;
 
        vis[x0][y0]=1;
        dfs(x0,y0,1);
        cout<<cnt<<endl;
    }
    return 0;
}

四、信息学OJ  1221:分成互质组

【题目描述】

给定n个正整数,将它们分组,使得每组中任意两个数互质。至少要分成多少个组?

【输入】

第一行是一个正整数n。1 <= n <= 10。

第二行是n个不大于10000的正整数。

【输出】

一个正整数,即最少需要的组数。

【输入样例】

6
14 20 33 117 143 175

【输出样例】

3

(2)代码实现

         

#include <bits/stdc++.h>
using namespace std;
const int MAXN=10500;
int a[MAXN];
int cnt[MAXN];
int t;
bool ok(int x)   
{
    for(int i=2; i<x; i++)
    {
        if(x%i==0)
        {
            if(cnt[i]) 
            {
                return false;
            }else
            {
                cnt[i]++;
            }
        }
    }
    return true;
}
void dfs(int k,int x)
{
    for(int i=k; i<t; i++)      
    {
        if(ok(a[i]))    
        {
            a[i]=-1;        
            k++;
            dfs(k,a[k]);   
        }
    }
    return ;
}
int main()
{
    int i,ans=0;
    cin>>t;
    for(i=0; i<t; i++)
    {
        cin>>a[i];
    }
    for(i=0; i<t; i++)
    {
        if(a[i]!=-1)
        {
            ans++; 
            memset(cnt,0,sizeof(cnt));
            dfs(i,a[i]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

五、信息学OJ 1222:放苹果

        

【题目描述】

把MM个同样的苹果放在NN个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用KK表示)5,1,11,5,1 是同一种分法。

【输入】

第一行是测试数据的数目tt(0≤t≤200≤t≤20)。以下每行均包含二个整数MM和NN,以空格分开。1≤M,N≤101≤M,N≤10。

【输出】

对输入的每组数据MM和NN,用一行输出相应的K。

【输入样例】

1
7 3

【输出样例】

8

(2)代码实现

        

#include<iostream>
using namespace std;
int n,m,t,ans=0;
void dfs(int apple,int plant,int last){
	if(m==apple&&n==plant){
		ans++;
		return;
	}
	if(apple>m||n==plant){
		return;
	}
	for(int i=last;i<=m;i++){
		dfs(apple+i,plant+1,i);
	}
}
int main(){
	cin>>t;
	while(t--){
		cin>>m>>n;
		ans=0;
		dfs(0,0,0);
		cout<<ans<<endl;
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值