1. 恐怖服装
题目描述:给定N个数和一个长度上限s,在N个数中选取两个数,要求相加不超过s,求出N个数中所有满足条件的对数(注意:4,5和5,4视为同一对)
数据规模:
2<=N<=20000,1<=s<=1000000
基本思路:
暴力枚举每一对,一旦符合就计数器++。
但此题数据范围较大,两重循环枚举的时间复杂度就是O(20000*20000),肯定会超时,所以要换一种思路:
先快排,排完序后的数列去枚举就可以加一些优化,就不会超时了。
想到这点,这道题基本没难度
附代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
intn,k,s=0,a[30000]={};
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n-1;i++)
for(int j=i+1;j<=n;j++)
if (a[i]+a[j]<=k) s++;
else break;//优化,一旦相加已经比上限大了(注意是数列是有序的),则结束当前循环(因为继续枚举也肯定比上限大了)
cout<<s;
return0;
}
2.密码锁
题目描述:给定一个N,再给定两个密码(每个密码都是三位数),若你输入的密码与两个密码中的其中一个每一位相差不超过二(N与1相连),则视为密码正确。
例:给定两串密码分别为(1,2,3)与(4,5,6)。此时,你输入(1,N,5)或(2,4,8)都视为密码正确。
求当最大数字为N时,共有几对正确密码。
数据范围:
1<=N<=100
基本思路:
因此题数据不大,可以直接三重循环枚举,再判断,统计,就可以求出方案数。
本题的难点就在于如何打判断条件(注意1与N相连)
核心的判断语句就为
Abs(x-y)<=2 或者 abs(x-y)>=N-2(判断环)
想到这些这题就没难度了
但我一次做时并没有想清判断条件
于是一个超长的判断语句出现了:
if (abs(i-x)<=2||abs(i-x)-n>=-2&&abs(j-y<=2)||abs(j-y)-n>=-2&&abs(k-z)<=2||abs(k-z)-n>=-2)s++
else(abs(i-a)<=2||abs(i-a)-n>=-2&&abs(j-b<=2)||abs(j-b)-n>=-2&&abs(k-c)<=2||abs(k-c)-n>=-2)s++;
(x,y,z和a,b,c分别表示两组给定密码,i,j,k为枚举变量);
对比两个表达式,无奈。。
此题还有一个需要注意的地方:
与两组密码比较时要分开比,不然会错位比较(找不出更好的词了。。)
例如:两组密码分别为(1,2,3)(4,5,6)那么(6,N,7)判断后就是成立的(实际上不成立)(因为6与4相比通过了,N与1相比通过了,7与6相比通过了)(第一次做时就被坑到了,印象深刻。。)