赞
踩
题目描述
有一个 n×m 方格的棋盘,求其方格包含多少正方形、长方形(不包含正方形)。
输入格式
一行,两个正整数 n,m(n≤5000,m≤5000)。
输出格式
一行,两个正整数,分别表示方格包含多少正方形、长方形(不包含正方形)。
输入 #1
2 3
输出
8 10
矩形由两条横线和两条竖线组成,n*m的格子中,有(n+1)条横线和(m+1)条竖线,各自任选2条,组成一个矩形。因此可以得出:长方形+正方形=(n+1)*n/2 * (m+1)*m/2 个,而正方形,可以枚举边长得出,变长为1的有m*n个;边长为2的有(m-1)*(n-1)个...直到边长为min(n,m)的有(n-min+1)*(m-min+1)个,然后相加可得正方形个数,相减可得长方形个数。
这里面变量最好全部定义为long long!感觉像是一道数学题,在草稿纸上枚举找规律
- #include<iostream>
- using namespace std;
-
- //统计正方形
- int main()
- {//都用longlong,要不过不了(wuwu~~)
- long long n,m,t;
- cin>>n>>m;
- t=min(n,m);
- long long ans1=0,ans2,sum=0;
- sum=((n+1)*n/2)*((m+1)*m/2);//总共矩形的数量
- for(long long i=1;i<=t;i++) ans1+=(n-i+1)*(m-i+1);//正方形数量
- ans2=sum-ans1;
- cout<<ans1<<" "<<ans2<<endl;
- return 0;
- }
题目描述
猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 10 种配料(芥末、孜然等),每种配料可以放 1 到 3 克,任意烤鸡的美味程度为所有配料质量之和。
现在, Hanke 想要知道,如果给你一个美味程度 n ,请输出这 10 种配料的所有搭配方案。
输入格式
一个正整数 n,表示美味程度。
输出格式
第一行,方案总数。
第二行至结束,10 个数,表示每种配料所放的质量,按字典序排列。
如果没有符合要求的方法,就只要在第一行输出一个 0。
输入 #1
11
输出
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% 的数据,n≤5000。
暴力:10个for循环,哈哈哈
- #include<iostream>
- using namespace std;
- int main()
- {
- int a,b,c,d,e,f,g,h,i,j,in,x=0;
- cin>>in;
- for (a=1;a<=3;a++)
- {
- for (b=1;b<=3;b++)
- {
- for (c=1;c<=3;c++)
- {
- for (d=1;d<=3;d++)
- {
- for (e=1;e<=3;e++)
- {
- for (f=1;f<=3;f++)
- {
- for (g=1;g<=3;g++)
- {
- for(h=1;h<=3;h++)
- {
- for (i=1;i<=3;i++)
- {
- for (j=1;j<=3;j++)
- {
- if (a+b+c+d+e+f+g+h+i+j==in)
- {
- x++;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- cout<<x<<endl;
- for (a=1;a<=3;a++)
- {
- for (b=1;b<=3;b++)
- {
- for (c=1;c<=3;c++)
- {
- for (d=1;d<=3;d++)
- {
- for (e=1;e<=3;e++)
- {
- for (f=1;f<=3;f++)
- {
- for (g=1;g<=3;g++)
- {
- for(h=1;h<=3;h++)
- {
- for (i=1;i<=3;i++)
- {
- for (j=1;j<=3;j++)
- {
- if (a+b+c+d+e+f+g+h+i+j==in)
- {
- cout<<a<<" ";
- cout<<b<<" ";
- cout<<c<<" ";
- cout<<d<<" ";
- cout<<e<<" ";
- cout<<f<<" ";
- cout<<g<<" ";
- cout<<h<<" ";
- cout<<i<<" ";
- cout<<j<<endl;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
题目描述
将1,2,…,9 共 9 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!
。
输入格式
三个数,A,B,C。
输出格式
若干行,每行 3 个数字。按照每行第一个数字升序排列。
输入
1 2 3
输出
192 384 576 219 438 657 273 546 819 327 654 981
说明/提示
保证 A<B<C。
- #include<iostream>
- using namespace std;
-
- //三连击
- #include<cstring>
- int a[10],b1,b2,b3,l=0,k1,k2,k3,ans=0;
- int main ()
- {
- cin >>k1>>k2>>k3;
- for (int b=1;b<=1000/k3;++b)
- {
- b1=b*k1;//求出三个数
- b2=b*k2;
- b3=b*k3;
- if (b2>987||b3>987)break;
- for (int c=1;c<=3;++c){//将三个数进行分解,判断是否重复
- a[b1%10]++;
- b1/=10;
- }for (int c=1;c<=3;++c){
- a[b2%10]++;
- b2/=10;
- }for (int c=1;c<=3;++c){
- a[b3%10]++;
- b3/=10;
- }for (int c=1;c<=9;++c)
- if (a[c]!=1){
- l=1;
- break;
- }
- memset(a,0,sizeof(a));
- if(l==0){
- cout <<b*k1 <<" " <<b*k2 <<" " <<b*k3 <<endl;
- ans++;
- }//将解输出,并做标记
- else l=0;//恢复为0,方便下一种情况的判断
- }
- if (!ans)cout <<"No!!!";
- return 0;
- }
题目描述
已知 n 个整数 x1,x2,⋯,xn,以及 1 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22
3+7+19=29
7+12+19=38
3+12+19=34
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29。
输入格式
第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)。
第二行 n 个整数,分别为 x1,x2,⋯,xn(1≤xi≤5×10^6)。
输出格式
输出一个整数,表示种类数。
输入
4 3 3 7 12 19
输出
1
- #include<iostream>
- using namespace std;
-
- //选数
- #include<cmath>
- int x[20],n,k,ans=0;
- bool b[20];
- bool isPrime(int n){
- if(n==1) return false;
- for(int i=2;i<sqrt(n);i++){
- if(n%i==0) return false;
- }
- return true;
- }
- void dfs(int start,int sum){
- if(sum==k){
- int s=0;
- for(int i=0;i<n;i++){
- if(b[i]) s+=x[i];
- }
- if(isPrime(s)) ans++;
- return ;
- }
- for(int i=start;i<n;i++){
- if(!b[i]){
- b[i]=true;
- dfs(i,sum+1);
- b[i]=false;
- }
- }
- }
- int main()
- {
- cin>>n>>k;
- for(int i=0;i<n;i++) cin>>x[i];
- dfs(0,0);//递归枚举
- cout<<ans<<endl;
- return 0;
- }
题目描述
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你输出所有组合。
例如n=5,r=3,所有组合为:
123,124,125,134,135,145,234,235,245,345
输入格式
一行两个自然数n,r(1<n<21, 0≤r≤n)。
输出格式
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
**注意哦!输出时,每个数字需要3个场宽
输入
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
- #include<iostream>
- using namespace std;
-
- //组合数的输出
- #include<algorithm>
- #include<iomanip>
- int r,n,a[25]={0};
- int main()
- {
- int n,r;
- cin>>n>>r;
- for(int i=r+1;i<=n;i++)
- a[i]=1;//保证只输出r个数
- do{
- for(int i=1;i<=n;i++)
- if(a[i]==0) cout<<setw(3)<<i;
- cout<<endl;
- } while(next_permutation(a+1,a+n+1));//下一个排列(按字典序一个一个next)
- return 0;
- }
题目描述
按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入格式
一个整数 n。
输出格式
由 1∼n 组成的所有不重复的数字序列,每行一个序列。
每个数字保留 5 个场宽。
输入
3
输出
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
说明/提示
1≤n≤9。
- #include<iostream>
- using namespace std;
-
- //全排列问题
- #include<iomanip>
- #include<algorithm>
- int n,a[10];
- int main()
- {
- cin>>n;
- for(int i=1;i<=n;i++)
- a[i]=i;
- do{
- for(int i=1;i<=n;i++)
- cout<<setw(5)<<a[i];
- cout<<endl;
- }while(next_permutation(a+1,a+n+1));
- return 0;
- }
人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回答。
火星人用一种非常简单的方式来表示数字――掰手指。火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为 1,2,3,⋯。火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的。
一个火星人用一个人类的手演示了如何用手指计数。如果把五根手指――拇指、食指、中指、无名指和小指分别编号为 1,2,3,4 和 5,当它们按正常顺序排列时,形成了 5 位数 12345,当你交换无名指和小指的位置时,会形成 5 位数 12354,当你把五个手指的顺序完全颠倒时,会形成 54321,在所有能够形成的 120 个 5 位数中,12345 最小,它表示 1;12354 第二小,它表示 2;54321 最大,它表示 120。下表展示了只有 3 根手指时能够形成的 6 个 3 位数和它们代表的数字:
三进制数 | 代表的数字 |
---|---|
123 | 1 |
132 | 2 |
213 | 3 |
231 | 4 |
312 | 5 |
321 | 6 |
现在你有幸成为了第一个和火星人交流的地球人。一个火星人会让你看他的手指,科学家会告诉你要加上去的很小的数。你的任务是,把火星人用手指表示的数与科学家告诉你的数相加,并根据相加的结果改变火星人手指的排列顺序。输入数据保证这个结果不会超出火星人手指能表示的范围。
输入格式
共三行。
第一行一个正整数 N,表示火星人手指的数目(1≤N≤10000)。
第二行是一个正整数 M,表示要加上去的小整数(1≤M≤100)。
下一行是 1 到 N 这 N 个整数的一个排列,用空格隔开,表示火星人手指的排列顺序。
输出格式
N 个整数,表示改变后的火星人手指的排列顺序。每两个相邻的数中间用一个空格分开,不能有多余的空格。
输入
5 3 1 2 3 4 5
输出
1 2 4 5 3
说明/提示
对于 100% 的数据,N≤10000。
- #include<iostream>
- using namespace std;
-
- //火星人
- #include<algorithm>
- int n,m,a[10001];
- int main()
- {
- cin>>n>>m;
- for(int i=1;i<=n;i++)
- cin>>a[i];
- int t=0;
- while(t!=m){
- t++;
- next_permutation(a+1,a+n+1);
- }
- for(int i=1;i<=n;i++)
- cout<<a[i]<<" ";
- return 0;
- }
题目描述
某国法律规定,只要一个由 N×M 个小方块组成的旗帜符合如下规则,就是合法的国旗。
现有一个棋盘状的布,分成了 N 行 M 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成该国国旗,方法是在一些格子上涂颜料,盖住之前的颜色。
小a很懒,希望涂最少的格子,使这块布成为一个合法的国旗。
输入格式
第一行是两个整数 N,M。
接下来 N 行是一个矩阵,矩阵的每一个小方块是W
(白),B
(蓝),R
(红)中的一个。
输出格式
一个整数,表示至少需要涂多少块。
输入
4 5 WRWRW BWRWB WRWRW RWBWR
输出
11
说明/提示
样例解释
目标状态是:
- WWWWW
- BBBBB
- RRRRR
- RRRRR
一共需要改 11 个格子。
数据范围
对于 100% 的数据,N,M≤50。
枚举红蓝与蓝白的分界线
- #include<iostream>
- using namespace std;
-
- //涂国旗
- int n,m,ans,minn=1e9;
- char mp[50][50];
- int main()
- {
- int i,j,k,l;
- cin>>n>>m;
- for(i=0;i<n;i++)
- for(j=0;j<m;j++)
- cin>>mp[i][j];
- for(i=0;i<n-2;i++)//最后至少有两行不是白色(枚举白蓝分界线)
- for(j=i+1;j<n-1;j++){//最后至少一行红色(枚举蓝红分界线)
- ans=0;
- for(k=0;k<=i;k++)//当,前i行是白
- for(l=0;l<m;l++)
- if(mp[k][l]!='W') ans++;
- for(k=i+1;k<=j;k++)//当,第i到j行是蓝色
- for(l=0;l<m;l++)
- if(mp[k][l]!='B') ans++;
- for(k=j+1;k<n;k++)//当j到n行是红色
- for(l=0;l<m;l++)
- if(mp[k][l]!='R') ans++;
- minn=min(ans,minn);
- }
- cout<<minn<<endl;
- return 0;
- }
题目描述
我们Aqours的成员要怎么在里面列队站下呢?
我们浦之星女子学院的篮球场是一个R行C列的矩阵,其中堆满了各种学校的杂物 (用"#"表示),空地 (用"."表示) 好像并不多的样子呢……
我们Aqours现在已经一共有K个队员了,要歌唱舞蹈起来的话,我们得排成一条1*K的直线,一个接一个地站在篮球场的空地上呢 (横竖均可)。
我们想知道一共有多少种可行的站位方式呢。
Aqours的真正的粉丝的你,能帮我们算算吗?
输入格式
第一行三个整数 R, C, K。
接下来的R行C列,是浦之星女子学院篮球场。
输出格式
总共的站位方式数量。
输入
5 5 2 .###. ##.#. ..#.. #..#. #.###
输出
8
- R C K 备注
- 1-2 <=10 <=10 <=min(R,C) 无
- 3-4 <=100 <=100 1 无
- 5-6 <=100 <=100 <=min(R,C) 没有障碍
- 7-10 <=100 <=100 <=min(R,C) 无
1. l长度的空地,k个人站成一排,共有l-k+1中方案。(这个好像没什么用)
2. 当k=1时,横竖站都是一样的,因此最后 答案/2。...每行每列搜索一遍...
- #include<iostream>
- using namespace std;
-
- //first step(搜索)
- int r,c,k,ans=0;
- char mp[101][101];
- int main()
- {
- cin>>r>>c>>k;
- for(int i=0;i<r;i++)
- for(int j=0;j<c;j++)
- cin>>mp[i][j];
- int f;
- for(int i=0;i<r;i++){//纵向搜索
- for(int j=0;j<c;j++){
- f=1;
- for(int s=0;s<k;s++){
- if(mp[i+s][j]!='.'){
- f=0;
- break;
- }
- }
- if(f==1) ans++;
- }
- }
- for(int i=0;i<r;i++){//横向搜索
- for(int j=0;j<c;j++){
- f=1;
- for(int s=0;s<k;s++){
- if(mp[i][j+s]!='.'){
- f=0;
- break;
- }
- }
- if(f==1) ans++;
- }
- }
- if(k==1) ans/=2;
- cout<<ans<<endl;
- return 0;
- }
题目描述
因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。
写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)( 一亿)间的所有回文质数。
输入格式
第 1 行: 二个整数 a 和 b .
输出格式
输出一个回文质数的列表,一行一个。
输入
5 500
输出
5 7 11 101 131 151 181 191 313 353 373 383
说明/提示
提示 1: 找出所有的回文数再判断它们是不是质数(素数).
提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。(可以转化为字符串处理)
产生长度为5的回文数:
- for (d1 = 1; d1 <= 9; d1+=2) { // 只有奇数才会是素数
- for (d2 = 0; d2 <= 9; d2++) {
- for (d3 = 0; d3 <= 9; d3++) {
- palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
- }
- }
- }
1. 除了11以外,一个数的位数是偶数的话,不可能为回文数素数。(因为 如果一个回文素数的位数是偶数,则它的奇数位上的数字和与偶数位上的数字和必然相等;根据数的整除性理论,容易判断这样的数肯定能被11整除,所以它就不可能是素数)
不判段位数的话会超时,呜呜呜~~~
- #include<iostream>
- using namespace std;
-
- //回文质数
- #include<cstring>
- #include<cstdio>
- int a,b;
- bool isprime(int n){
- if(n==1) return false;
- for(int i=2;i*i<=n;i++){
- if(n%i==0) return false;
- }
- return true;
- }
- bool check(int n){//判断回文数
- string s=to_string(n);
- for(int i=0;i<s.size();i++){
- if(s[i]!=s[s.size()-1-i])
- return false;
- }
- return true;
- }
- int main()
- {
- cin>>a>>b;
- b=min(b,9999999);//大于9999999的数都不可能是质数回文
- for(int i=a;i<=b;i++){
- if((i>=1000&&i<=9999)||(i>=100000&&i<=999999))
- continue;
- if(check(i)&&isprime(i))
- printf("%d\n",i);//打印比cout快
- }
- return 0;
- }
题目描述
给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0−9的拼法如图所示:
注意:
加号与等号各自需要两根火柴棍
如果A≠B,则A+B=C与B+A=C视为不同的等式(A,B,C>=0)
n根火柴棍必须全部用上
输入格式
一个整数n(n<=24)。
输出格式
一个整数,能拼成的不同等式的数目。
输入1
14
输出
2
输入 2
18
输出
9
说明/提示
【输入输出样例1解释】
2个等式为0+1=1和1+0=1。
【输入输出样例2解释】
9个等式为:
- 0+4=4
- 0+11=11
- 1+10=11
- 2+2=4
- 2+7=9
- 4+0=4
- 7+2=9
- 10+1=11
- 11+0=11
如果是111+0=111的话用掉22根,如果是1111+0=1111的话用掉26根所以24根应该在1111之内
- #include<iostream>
- using namespace std;
-
- //火柴棒等式
- int num[10]={6,2,5,5,4,5,6,3,7,6};//0~9对应的火柴个数
- int match(int n){
- int i,sum=0;
- for(i=n;i!=0;i/=10){//2位以上首位不能为0
- sum+=num[i%10];
- }
- if(n==0) sum+=num[0];//单个0单独判断
- return sum;
- }
- int main()
- {
- int i,j,ans=0,n;
- cin>>n;
- for(i=0;i<1111;i++){//除去4个火柴做符号,最多20个火柴凑数字,1000正好需要20根
- for(j=0;j<1111;j++){
- if(match(i)+match(j)+match(i+j)+4==n)
- ans++;
- }
- }
- cout<<ans<<endl;
- return 0;
- }
题目描述
有 n 根木棒,现在从中选 4 根,想要组成一个正三角形,问有几种选法?
答案对 10^9+7 取模。
输入格式
第一行一个整数 n。
第二行 n 个整数,第 i 个整数 ai 代表第 i 根木棒的长度。
输出格式
一行一个整数代表答案。
输入
4 1 1 2 2
输出
1
说明/提示
数据规模与约定
- #include<iostream>
- using namespace std;
-
- //妖梦拼木棒
- typedef long long ll;
- const ll mod=1e9+7;
- ll n,maxa=-1,ans;
- ll a[100005],num[100005];
- ll C2(int k){
- return ((k*(k-1))/2)%mod;
- }
- int main(){
- cin>>n;
- for (ll i=1;i<=n;i++) {
- cin>>a[i];
- maxa=max(maxa,a[i]);
- num[a[i]]++;
- }
- for (ll i=1;i<=maxa;i++){
- for (ll j=i;j<=maxa;j++){
- if (i==j) ans=(ans+(C2(num[i])*C2(num[i+j])))%mod;
- else ans=(ans+((num[i]*num[j])%mod*C2(num[i+j]))%mod)%mod;
- }
- }
- cout<<ans<<endl;
- return 0;
- }
题目描述
Perket 是一种流行的美食。为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽可能获得最全面的味道。你有 n 种可支配的配料。对于每一种配料,我们知道它们各自的酸度 s 和苦度 b。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的苦度为每一种配料的苦度的总和。
众所周知,美食应该做到口感适中,所以我们希望选取配料,以使得酸度和苦度的绝对差最小。
另外,我们必须添加至少一种配料,因为没有任何食物以水为配料的。
输入格式
第一行一个整数 n,表示可供选用的食材种类数。
接下来 n 行,每行 2 个整数 si 和 bi,表示第 i 种食材的酸度和苦度。
输出格式
一行一个整数,表示可能的总酸度和总苦度的最小绝对差。
输入 #1
1 3 10
输出
7
输入 #2
2 3 8 5 8
输出
1
输入 #3
4 1 7 2 6 3 8 4 9
输出
1
说明/提示
数据规模与约定
对于 100% 的数据,有 1≤n≤10,且将所有可用食材全部使用产生的总酸度和总苦度小于 1×10^9,酸度和苦度不同时为 1 或 0。
- #include<iostream>
- using namespace std;
-
- //PERKET
- #include<cmath>
- int n,s[11],b[11],ans=1e9;//最多10种配料
- void dfs(int i,int x,int y){//第i种配料,x酸度,y苦度
- if(i>n){//大于n表示全部搜索完了
- if(x==1&&y==0) return ;//判断清水的情况
- ans=min(abs(x-y),ans);//更新ans
- return ;
- }
- dfs(i+1,x*s[i],y+b[i]);//添加第i种配料
- dfs(i+1,x,y);//不添加第i种配料
- }
- int main()
- {
- cin>>n;
- for(int i=1;i<=n;i++)
- cin>>s[i]>>b[i];
- dfs(1,1,0);
- cout<<ans<<endl;
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。