12.3(1)

来源:互联网 发布:极简生活后的变化知乎 编辑:程序博客网 时间:2024/06/13 23:08

题解(1.2

1.奶牛的服装

有一套衣服,长度为s1<=s<=1,000,000),有奶牛n头(2<=n<=2,000,000),两头奶牛可以组成一组,穿这套衣服。已知每头奶牛的长度(1<=Li<=1000),求共有几种搭配方法。

【输入】

* 第1行: 2个用空格隔开的整数:N 和 S
    * 第2..N+1行: 第i+1为1个整数:Li

【输出】

* 第1行: 输出1个整数,表示陈亮宇可选择的所有方案数。注意奶牛顺序不同的两种
方案是被视为相同的

 

【输入输出样例1

halloweena.in

halloween.out

4 6

3

5

2

1

 

4

 

这道题目比较简单,数据没有很大,不必担心超时或空间不足。

思路:

1. 读入数据

2. 将所有的数排序(可以不排序直接进行枚举)

3. 枚举所有的可能性:枚举的所有的可能性需要双重循环,要避免重复的方案数,所以我们设第一个重循环的变量为i,第二重循环的变量为jj的初始值要大于i,这样就可以避免重复,每一组数据的编号都是先小后大,不存在重复。

优化版:

1. 第一步还是一样,读入数据

2. 将所有的数据排序,从小到大

3. 枚举所有的可能性时,如果此时的Li加上Lj要大于服装的长度s,因为后面L要大于现在的长度Lj,那么后面的方案一定是不可行的,所以我们就没必要进行后面j的累加试验。适当使用break退出循环。这样是程序的运行时间减少,进行优化。

程序:

#include<bits/stdc++.h>

using namespace std;

int main()

{

int n,s;

int l[22222];

cin>>n>>s;//读入

for(int i=1;i<=n;i++)

cin>>l[i];

sort(l+1,l+n+1);//排序(此程序可以省略)

int num=0;//统计

for(int i=1;i<=n-1;i++)

 for(int j=i+1;j<=n;j++)

 if(l[i]+l[j]<=s)

 num+=1;//数据统计

 cout<<num<<endl;

 return 0;

}

上面的程序没有进行优化,所以耗时要长。在做这道题时,没有想到这么多,所以在思路上还有欠缺,问题思考不够全面。

改进后(主体):

For(int i=1;i<=n;i++)

 For(int j=i+1;j<=n;j++)

If(l[i]+l[j]<=s)

Num+=1;

Else

 Break;

下一题

2. 破锁

一把锁有两个密码,都是三位,每个数字都是1-n的整数,是个环形圈数,即n1相邻。这个锁有误差,若每位数字都与两个密码中其中一个密码的每位数字相差不到2,及该数字组合就与密码相近,可以打开锁。求可以打开锁的所有方案数。

【输入】

第一行:一个整数n
第二行:3个用空格分开的整数,代表第一个密码
第三行:3个用空格分开的整数,代表第二个的密码(很可能和第一个密码相同)

【输出】

密码数

【输入输出样例1

lock.in

lock.out

50

1 2 3

5 6 7

249

 

思路:
每个数都可以与相邻的数相差2,所以每一位都有五种可能性,这样总共就有5*5*5*2种,即250种可能性,其中可能含重复的部分所以我们要减去因重复而多算的那几种可能性。每一位的两个数字相邻可以用来两个数学表达式来表示Abs(x-y)<=2   或者abs(x-y)>=N-2只要满足这两个条件就知道这一位的两个数字是相邻的。

程序:

#include<bits/stdc++.h>

using namespace std;

int main()

{

int n;

cin>>n;

int a[4][6],b[4][6];

cin>>a[1][3]>>a[2][3]>>a[3][3]>>b[1][3]>>b[2][3]>>b[3][3];

int maxx=250;//先将所有的可能性都算上

for(int i=1;i<=3;i++)

 for(int j=-2;j<=2;j++)

 a[i][j+3]=a[i][3]+j;

for(int i=1;i<=3;i++)

 for(int j=-2;j<=2;j++)

 b[i][j+3]=b[i][3]+j;

for(int i=1;i<=3;i++)

 for(int j=1;j<=5;j++)

 if(a[i][j]<1)

 a[i][j]+=n;

for(int i=1;i<=3;i++)

 for(int j=1;j<=5;j++)

 if(b[i][j]<1)

 b[i][j]+=n;//计算每个数位的范围内的数

  for(int j=1;j<=5;j++)

   for(int k=1;k<=5;k++)

    if(a[1][j]==b[1][k]&&a[2][j]==b[2][k]&&a[3][j]==b[3][k])

   maxx-=1;//比较,若有重复减去

cout<<maxx<<endl;

return 0;   

}

(未正确,还未正解,后补)

优化:只要判断每个数的最大值和最小值即可,减少了几个判断循环