2022年3月30日(作业三题解)

P2089 烤鸡

模拟

枚举每一种配料

和为n时方案总数sum++;

如果 if sum为0时直接输出0

否则 else

再枚举每一种配料

和为n时

输出方案

#include<bits/stdc++.h>
using namespace std;

int n;
int sun;

int main()//枚举
{
    cin>>n;
    for(int i1=1;i1<=3;i1++)
        for(int i2=1;i2<=3;i2++)
            for(int i3=1;i3<=3;i3++)
                for(int i4=1;i4<=3;i4++)
                    for(int i5=1;i5<=3;i5++)
                        for(int i6=1;i6<=3;i6++)
                            for(int i7=1;i7<=3;i7++)
                                for(int i8=1;i8<=3;i8++)
                                    for(int i9=1;i9<=3;i9++)
                                        for(int i10=1;i10<=3;i10++)
                                            if(i1+i2+i3+i4+i5+i6+i7+i8+i9+i10==n)
                                            {
                                                sun++;
                                            }
    if(sun==0)cout<<0;
    else cout<<sun<<endl;
    for(int i1=1;i1<=3;i1++)
        for(int i2=1;i2<=3;i2++)
            for(int i3=1;i3<=3;i3++)
                for(int i4=1;i4<=3;i4++)
                    for(int i5=1;i5<=3;i5++)
                        for(int i6=1;i6<=3;i6++)
                            for(int i7=1;i7<=3;i7++)
                                for(int i8=1;i8<=3;i8++)
                                    for(int i9=1;i9<=3;i9++)
                                        for(int i10=1;i10<=3;i10++)
                                            if(i1+i2+i3+i4+i5+i6+i7+i8+i9+i10==n)
                                            {
                                                cout<<i1<<" "<<i2<<" "<<i3<<" "<<i4<<" "<<i5<<" "<<i6<<" "<<i7<<" "<<i8<<" "<<i9<<" "<<i10<<" "<<endl;
                                            }
    
    return 0;
}

P1605 迷宫

dfs深搜

使用深搜一个个查,使用一个数组b记录障碍的地方;

int xx[4]={0,1,0,-1};
int yy[4]={1,0,-1,0};

如果没有障碍并且不是自己走过的,就进一步搜索,把自己走过的路打上标记,返回时,再将标记还原;

#include<bits/stdc++.h>
using namespace std;

int a[10][10],b[10][10]; 
int n,m,t;
int sx,sy,fx,fy;
int x,y,ant;
int xx[4]={0,1,0,-1};
int yy[4]={1,0,-1,0};

void dfs(int aa1,int aa2)//dfs过程中的x,y
{
    if(aa1==fx&&aa2==fy)dfs过程中的x,y等于终点时
    {
        ant++;
        return;
    }
    for(int i=0;i<4;i++)
    {
        int l=aa1+xx[i];int r=aa2+yy[i];
        if(l>=1&&r>=1&&l<=n&&r<=m&&b[l][r]==0&&a[l][r]==0)//边界未标记无障碍
        {    
            b[l][r]=1;//标记    
            dfs(l,r);
            b[l][r]=0;//还原    
        }
        
    }
}

int main()
{
    cin>>n>>m>>t;
    cin>>sx>>sy>>fx>>fy;
    a[sx][sy]=1;
    while(t--)
    {
        cin>>x>>y;
        a[x][y]=1;
    }
    dfs(sx,sy);
    cout<<ant;
 } 

P3799 妖梦拼木棒

欲由4根木棒组成一个正三角形,则必有 2根长度相等
且另外2根长度之和,等于 前2根相等的木棒 的长度

发现 木棍 的最大长度 
暴力枚举 最大长度,计算方案数并累加。

 易知:a=b=c+d
         一、即先取两支一样长且长度为i的木棍
         二、再从比i长度小的木棍取两支木棍j、i-j
              ①j == i-j,从相同长度木堆取两个
              ②j != i-j,从不同长度两个木堆分别取一个
              ③为避免取重复,应控制 j < i - j,即j < i / 2

 

import java.util.Scanner;

public class Main {
    
    static Scanner sc;
    static int MO = 1000000007;
    static int n;//n个数
    static int[] num;//存储每个数字出现的个数
    static int max = 0;//存储木棍长度最大值
    static int temp;//临时变量存储sc.nextInt()
    static int sum = 0;
    
    
    public static void main(String[] args) {
        //初始化
        sc = new Scanner(System.in);
        n = sc.nextInt();
        num = new int[5001];
        
        for (int i = 0; i < n; i++) {
            temp = sc.nextInt();
            if (temp > max) {
                max = temp;
            }
            num[temp]++;
        }
        
        //如果从长度为1的木堆开始取两个,很明显没有这种情况,因此从长度为2的木堆开始取
        for (int i = 2; i <= max; i++) {
            if (num[i] >= 2) {//此木堆超过两支木棍
                 int fs = C(num[i], 2) % MO;
                //取完两支长短一样的木棍后,开始取另外两根长度未知的
                for (int j = 1; j <= i / 2; j++) {
                    //1、长度一样;那么就在同一木堆取两个
                    if (j == i - j && num[j] >= 2) {
                        sum = (sum + fs * C(num[j], 2)) % MO;
                    }
                    //2、长度不一样;那么就在两个不同木堆分别取一个
                    if (j != i - j && num[j] >= 1 && num[i-j] >= 1) {
                        sum = (sum + fs * C(num[j], 1) * C(num[i-j], 1)) % MO;
                    }
                }
            }
        }
        
        System.out.println(sum);
    }

    // 求组合数
    // 要么C(n,1) 要么C(n,2)
    public static int C(int k, int r) {
        if (r == 1) {
            return k % MO;
        }
        return (k * (k - 1) / 2) % MO;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值