链接:https://ac.nowcoder.com/acm/contest/11258#question
I题–xay loves or
题目链接:https://ac.nowcoder.com/acm/contest/11258/I
题意:
给你两个数 x,s求有多少个y满足: x or y = s
思路:
最主要的就是题目给的哪个 or,当初和队友闹意见,队友们认为这个 or 用代码写是 ||,是逻辑运算“或”,但问题是如果是 ||,那 x=1, s=1的话y不就随便取数了吗,而且y的取值范围你知道吗?所以这个 or 是位运算的“或”也就是 |。
我们最后的思路也就是纯暴力走,当然如果完全纯暴力1e10的量肯定超时,众所周知,a | b = c,这个c一定比a,b大,所以为了求b,我们设置<=c就好
AC代码:
#include<iostream>
using namespace std;
int main()
{
int x, s, ans = 0;
cin>>x>>s;
for(int i=1;i<=s;i++)
{
if((x|i)==s) ans++;
}
cout<<ans<<endl;
return 0;
}
H题–xay loves count
题目链接:https://ac.nowcoder.com/acm/contest/11258/H
题意:
给你一个长n的数组,求有多少三元组(i,j,k)满足ai * aj = ak (i,j,k可以相等)
思路:
这题是队友做出来的,利用了map和双指针,正好卡在超时的边界上:
通过双指标找出 i和j两个数 在通过i和j位置上的数来 运算出k的数,但是如果暴力的一次性去找时间绝对会超,本题不同位置上的相同数值仍为不同的方法。
但本题也并非让我们求i j k准确数据,所以我们可以利用map来将每一个数的个数进行存储。
在运算时直接使用map来代表一个整体,再将原数组的所有数去重,这样就减少了大部分的由于数组过长导致的超时。
然后再找出当有2个相同数时和3个相同数时(1)的特殊计算方法,最后求得总和。
AC代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <deque>
#include <set>
#include <stack>
#include <queue>
using namespace std;
const int N = 100050,mod = 1e9 ,INF = 0x3f3f3f3f;
typedef long long ll;
map<ll,int >s;
vector<ll>a;
int main()
{
ll n;scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
ll w;scanf("%lld",&w);
a.push_back(w);
s[w]++;
}
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
ll sum = 0;
for(int i=0;i<a.size();i++)
{
for(int j = i;j<a.size();j++)
{
if(a[i]*a[j]>a[a.size()-1])break;
if(s[a[i]*a[j]]==0)continue;
if(a[i]==a[j]&&a[i]!=1)
{
sum = sum+ s[a[i]]*s[a[j]]*s[a[i]*a[j]];
}//两个数相同 没有1
else if(a[i]==1&&a[j]!=1)
{
sum+= 2*s[a[i]]*s[a[j]]*s[a[j]];
}//两个数相同 有1
else if(a[i]==a[j]&&a[i]==1)
{
sum+=s[a[i]]*s[a[i]]*s[a[i]];
}//三个数为1
else
{
sum+=2*s[a[i]]*s[a[j]]*s[a[i]*a[j]];
}//三个都不同
}
}
printf("%lld\n",sum);
return 0;
}
其他的题等以后再补…