每日刷题——洛谷P2241、P2089、P1618

116 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

P2241 统计方形(数据加强版)

题目背景

1997年普及组第一题

题目描述

有一个 n×mn \times m 方格的棋盘,求其方格包含多少正方形、长方形(不包含正方形)。

输入格式

一行,两个正整数 n,mn,mn5000,m5000n \leq 5000,m \leq 5000)。

输出格式

一行,两个正整数,分别表示方格包含多少正方形、长方形(不包含正方形)。

样例 #1

样例输入 #1

2 3

样例输出 #1

8 10

思路

总矩形个数 = 正方形个数 + 长方形个数

先计算好计算的正方形个数,然后利用公式计算总矩形个数,最后得到长方形个数

代码

// P2241 统计方形(数据加强版)
#include<iostream>
using namespace std;
int main()
{
    long long n,m;
    long long squaresum = 0;    
    cin >> n >> m;
    long long sum ;
    sum = n*(n+1)*m*(m+1)/4;//总矩形
    for(long long i=1; i<=min(n,m); i++){
        squaresum += (m-i+1)*(n-i+1);
    }
    cout << squaresum << " " << sum - squaresum;
    return 0;
}

P1618 三连击(升级版)

题目描述

1,2,,91, 2,\ldots, 999 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A:B:CA:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!

//感谢黄小U饮品完善题意

输入格式

三个数,A,B,CA,B,C

输出格式

若干行,每行 33 个数字。按照每行第一个数字升序排列。

样例 #1

样例输入 #1

1 2 3

样例输出 #1

192 384 576
219 438 657
273 546 819
327 654 981

提示

保证 A<B<CA<B<C


upd 2022.8.3\text{upd 2022.8.3}:新增加二组 Hack 数据。

思路

暴力枚举

利用hash数组保证三个数的位数上数字各不相同

然后根据数学特性,缩小枚举范围,不优化会有部分TLE(ORZ

代码

// P1618 三连击(升级版)
#include<bits/stdc++.h>
using namespace std;
bool xx(int a, int b, int c){
    int hash[10] = {0};
    for(int i=0; i<3; i++){
        if(hash[a%10]) return false;
        else{
            hash[a%10] = 1;
            a/=10;
        }
    }
    for(int i=0; i<3; i++){
        if(hash[b%10]) return false;
        else{
            hash[b%10] = 1;
            b/=10;
        }
    }
    for(int i=0; i<3; i++){
        if(hash[c%10]) return false;
        else{
            hash[c%10] = 1;
            c/=10;
        }
    } 
    if(hash[1] && hash[2] && hash[3] && hash[4] && hash[5] && hash[6] && hash[7] && hash[8] && hash[9])
    return true;
    else return false;
}

int main(){
    int flag = 0;
    int hash[9];
    int a,b,c;
    cin >> a >> b >> c;
    for(int i=123; i<=340; i++)
        for(int j=2*i; j<=680; j++)
            for(int k=3*i; k<=987; k++)
                if(xx(i,j,k) && i*b/a == j && j*c/b == k){
                    flag = 1;
                    cout << i << " " << j << " " << k << endl;
                }else continue;
    if(!flag) cout << "No!!!";
    return 0;
}

P2089 烤鸡

题目背景

猪猪 Hanke 得到了一只鸡。

题目描述

猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 1010 种配料(芥末、孜然等),每种配料可以放 1133 克,任意烤鸡的美味程度为所有配料质量之和。

现在, Hanke 想要知道,如果给你一个美味程度 nn ,请输出这 1010 种配料的所有搭配方案。

输入格式

一个正整数 nn,表示美味程度。

输出格式

第一行,方案总数。

第二行至结束,1010 个数,表示每种配料所放的质量,按字典序排列。

如果没有符合要求的方法,就只要在第一行输出一个 00

样例 #1

样例输入 #1

11

样例输出 #1

10
1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 2 1 
1 1 1 1 1 1 1 2 1 1 
1 1 1 1 1 1 2 1 1 1 
1 1 1 1 1 2 1 1 1 1 
1 1 1 1 2 1 1 1 1 1 
1 1 1 2 1 1 1 1 1 1 
1 1 2 1 1 1 1 1 1 1 
1 2 1 1 1 1 1 1 1 1 
2 1 1 1 1 1 1 1 1 1

提示

对于 100%100\% 的数据,n5000n \leq 5000

思路

因为数据比较弱,直接暴力枚举

代码

// P2089 烤鸡
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    //int a[59050][10]={0};//栈溢出
    //用new方法从堆申请空间
    int **a = new int*[59050];
    for(int i=0; i<59050; i++){
        a[i] = new int[10];
    }

    int sum = 0;
    int count = 0;
    int index = 0;
    cin >> n;
    if(n>=10 && n<=30){
        for(int aa=1; aa<=3; aa++)
            for(int b=1; b<=3; b++)
                for(int c=1; c<=3; c++)
                    for(int d=1; d<=3; d++)
                        for(int e=1; e<=3; e++)
                            for(int f=1; f<=3; f++)
                                for(int g=1; g<=3; g++)
                                    for(int h=1; h<=3; h++)
                                        for(int i=1; i<=3; i++)
                                            for(int j=1; j<=3; j++)
                                                if(aa+b+c+d+e+f+g+h+i+j == n)
                                                {   count++;//方案数+1
                                                    a[index][0] = aa;
                                                    a[index][1] = b;
                                                    a[index][2] = c;
                                                    a[index][3] = d;
                                                    a[index][4] = e;
                                                    a[index][5] = f;
                                                    a[index][6] = g;
                                                    a[index][7] = h;
                                                    a[index][8] = i;
                                                    a[index][9] = j;
                                                    index++;}        
        cout << count<<endl;
        for(int y=0; y<index; y++){
            if(a[y][0]){
                for(int z=0; z<10; z++){
                    cout << a[y][z] << " ";
                }
                cout << endl;
            }
        }
    }else{
        cout << 0;
    }
    delete(a);
    return 0;
}