我一直在尝试编写一个程序,该程序检查列表L中是否有两个项的和等于给定的整数S,并打印找到的这两个项。如果没有可用的解决方案,程序将显示错误消息“!ok”。
输入: 在第一行上,将有一个整数T表示测试用例的数量,随后是每个测试用例的2条输入线: 在每个测试用例的第一行,将有2个整数S和E,其中S是期望的总和,E是列表中元素的数量。 在第二行上,将有E个整数,中间用空格隔开。 每个整数代表列表L的一个元素。这些元素不会以任何方式排序,并且某些元素可能具有相同的值。在数字E为0的情况下,第二行将为空。
列表L元素的所有值都将与值S处于同一范围。
输出: 对于每个测试用例,输出应包含以下内容: 如果有独特的解决方案,则应打印(列表L的)两个元素x和y,并用一个空格隔开。 如果有多个解决方案,则仅打印列表中显示的第一对完整对并提供正确的总和。 如果没有解决方法,应打印错误信息“!OK”。
约束和注意事项:
1≤T≤1000
-10 ^6≤S≤10^ 6
0≤E≤2⋅10^ 4
E的总和最多为10 ^ 7
为了执行该任务,我尝试使用哈希表,因为考虑到运行时的复杂性,在这种情况下使用数组可能会出现问题。
这是我的代码:
#include <iostream>
#include <bits/stdc++.h>
#include <set>
using namespace std;
int main()
{
long long int numberElements=0, number;
long long int sum=0, temp;
unordered_set<long long int> s;
bool found=0;
int numberCases;
cin >> numberCases;
for(int c = 1; c<=numberCases; c++)
{
s.clear();
cin >> sum;
found=0;
cin>> numberElements;
if(numberElements==0)
cout << "!OK" <<endl;
else
{
for(long long int i = 0; i< numberElements && found==0; i++)
{
cin >> number;
if (sum==(number+number))
{
if (s.find(number)!=s.end() )
{
cout<<number<<" "<<number<<endl;
found=1;
}
}
else
{
if(s.find(number)==s.end())
s.insert(number);
temp = sum - number;
if (s.find(temp)!=s.end())
{ cout<<temp<<" "<<number<<endl;
found=1;
}
}
}
if (found==0)
cout << "!OK" <<endl;
}
}
return 0;
}
对于以下输入:
6
8 4
1 2 4 4
8 4
1 2 7 9
8 4
1 2 8 9
8 4
4 5 3 4
8 4
4 1 1 8
8 4
-1 1 9 8
预期输出为:
4 4
1 7
!OK
3 5
!OK
-1 9
我的代码的输出实际上是:
!OK
1 7
1 8
4 5
!OK
!OK
我一直试图在代码中检测出导致不必要输出的问题根源,但是直到我的努力一直没有成功。
任何帮助将不胜感激。
答案 0 :(得分:0)
我做了一些修改。第一个创建了一个unordered_multiset,它允许存储重复的值(用于检查sum =(数字+数字))。 主要问题是您正在检查一个空列表,因此该问题从未找到任何要比较的值。 问候!
int main()
{
long long int numberElements = 0, number;
long long int sum = 0, temp;
unordered_multiset<long long int> s; //Change set to multiset because multicase store repeated values, set don´t
bool found = 0;
bool RepeatedValue = false;
int numberCases;
cin >> numberCases;
for (int c = 1; c <= numberCases; c++)
{
s.clear();
cin >> sum;
found = 0;
cin >> numberElements;
if (numberElements == 0)
cout << "!OK" << endl;
else
{
//This for is necesarry to charge the numbers before anlyze them.
//You were looking for a coincidence into a empty list
for (long long int i = 0; i < numberElements; i++)
{
cin >> number;
s.insert(number);
}
for (unordered_multiset<long long int>::iterator it = s.begin(); it != s.end() && found == 0;it++)
{
number = (*it);
if (sum == (number + number))
{
//I addded this new conditional because I fill the list before analyze other number
//In this case, use a find() is useless because always will a find a int of value "number"
//count() returns the repeated times that a value was repeated
if ( s.count(number) > 1)
{
cout << number << " " << number << endl;
found = 1;
}
}
else
{
//This conditional is unnecessary, is find() returns s.end()
//means that not found the required number
/*if (s.find(number) == s.end())
s.insert(number);*/
temp = sum - number;
if (s.find(temp) != s.end())
{
cout << temp << " " << number << endl;
found = 1;
}
}
}
if (found == 0)
cout << "!OK" << endl;
}
}
return 0;
}
答案 1 :(得分:0)
我刚刚成功编写了正确的解决方案。这是我的代码:
#include <iostream>
#include <bits/stdc++.h>
#include <set>
using namespace std;
int main()
{
long long int numberElements = 0, number;
long long int sum = 0, temp=0, element1=0, element2=0;
unordered_multiset<long long int> s;
bool found = 0;
int numberCases;
cin >> numberCases;
for (int c = 1; c <= numberCases; c++)
{
s.clear();
cin >> sum;
cin >> numberElements;
if (numberElements == 0)
cout << "!OK" << endl;
else
{
found=0;
for (long long int i = 0; i < numberElements; i++)
{
cin >> number;
s.insert(number);
if (found==0)
{
temp=sum-number;
if(temp==number)
{
if(s.count(temp)>1)
{
element1=number;
element2=number;
found=1;
}
}
else
{
if(s.find(temp)!=s.end())
{
element1=number;
element2=temp;
found=1;
}
}
}
}
if (found==1)
cout << min(element2,element1) << " " << max(element2, element1) << endl;
else
cout << "!OK" << endl;
}
}
return 0;
}