AcWing寒假入门班:找硬币
原题传送:AcWing 1532. 找硬币
题目:
伊娃喜欢从整个宇宙中收集硬币。
有一天,她去了一家宇宙购物中心购物,结账时可以使用各种硬币付款。
但是,有一个特殊的付款要求:每张帐单,她只能使用恰好两个硬币来准确的支付消费金额。
给定她拥有的所有硬币的面额,请你帮她确定对于给定的金额,她是否可以找到两个硬币来支付。
输入
第一行包含两个整数 N 和 M,分别表示硬币数量以及需要支付的金额。
第二行包含 N 个整数,表示每个硬币的面额。
输出
一行,包含两个整数 V1,V2,表示所选的两个硬币的面额,使得 V1≤V2 并且 V1+V2=M。
如果答案不唯一,则输出 V1 最小的解。
如果无解,则输出 No Solution。
数据范围
1≤N≤10^5
1≤M≤1000
输入样例
8 15
1 2 8 7 2 4 11 15
输出样例
4 11
思路:
这道题思路很容易想,普通解法就是每次输入一个数,然后用两个数组存这个数,一个是自己有的硬币,另一个是用来判断一个数在不在的。但第二个数组要开多大又是一个问题,其实我们可以再看一下数据范围,m最大是1000,而这道题目要求两个数加起来等于m而且所有输入的数均不为0,所以这个数组最大开到1000就足够了。接下来就循环n遍(也不一定要n遍,但n遍保险,而且10^5遍也不会超时),然后判断m-a[i]这个数是否存在,如果存在并且满足判断条件,就输出a[i]和m-a[i],结束程序,如果程序一直运行到了最后,就说明没有满足条件的数,就输出No Solution。
PS:输出前的判断条件要写准,不然会出错。
题目:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100010],b[100010];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[a[i]]++;
}
sort(a+1,a+1+n);
bool v=false;
for(int i=1;i<=n;i++)
{
if(b[m-a[i]]>1&&b[a[i]]+b[m-a[i]]>1)
v=true;
else if(b[m-a[i]]==1&&m-a[i]!=a[i])
v=true;
if(m-a[i]==0||a[i]==0)
v=false;
if(v)
{
cout<<a[i]<<" "<<m-a[i];
return 0;
}
}
cout<<"No Solution";
return 0;
}
这题不止这一种方法,还可以用哈希表 (我不会) 或双指针。