题目大意:给定一个长度为n的数组a,我们可以选择两个不同的整数i,j(1≤i<j≤n),用x替换ai,用y替换aj(x和y是非负整数)。为了不破坏数组,必须保持ai | aj = x | y,其中|表示按位or运算。
请输出使用上述运算任意次后所能得到的数组的最小和。
input
4 3 1 3 2 5 1 2 4 8 16 2 6 6 3 3 5 6output
3 31 6 7
性质: 0跟任何数进行按位或运算都是任何数;
数组的最小和=所有数字都进行一次按位或运算。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
using namespace std;
typedef long long LL;
LL a[200200];
int main()
{
// cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
LL sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(i==1) sum=a[1];
else sum|=a[i];
}
printf("%lld\n",sum);
}
return 0;
}
题目大意:给定一个长度为n的数组a,让我们对下标从2~n-1的这些数中做操作,使之他们的高度不能出现严格的山峰形状(山峰形状定义为:a[i-1]<a[i]>a[i+1]),问最小应改变几个数字?并将改动后的数组输出。
input
5 3 2 1 2 4 1 2 3 1 5 1 2 1 2 1 9 1 2 1 3 2 3 1 2 1 9 2 1 3 1 3 1 3 1 3output
0 2 1 2 1 1 3 3 1 1 1 2 2 2 1 2 1 2 3 3 2 3 3 2 1 2 2 1 3 3 3 1 1 1 3
一开始想复杂了觉得我不仅得考虑到前面的山峰也得顾及到后边的山峰,那这样去实现它就很麻烦。又想了一下因为它并没有要求我们把具体高度也作为指标所以可以不用这么麻烦,直接从前往后遍历然后山峰高度往后推即可。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
using namespace std;
int a[200200];
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
memset(a,0,sizeof a);
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int sum=0;
for(int i=2;i<n;i++)
{
if(a[i]>a[i-1]&&a[i]>a[i+1])
{
sum++;
a[i+1]=max(a[i],a[i+2]);
}
//cout<<a[i]<<" ";
}
//cout<<endl;
cout<<sum<<endl;
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
return 0;
}
题目大意:给定一个长度为n的数组a,我们可以执行以下操作不超过n次:选择三个索引x,y,z(1≤x<y<z≤n),并将ax替换为ay−az,即:a[x]=a[y]-a[z]。我们的目标是生成的数组不递减。(请注意:不必最小化此任务中的操作数量!!!)
如果可以达成目标的话输出操作数以及每次的三个索引。如果不能的话就输出-1。
input
3 5 5 -4 2 -1 2 3 4 3 2 3 -3 -2 -1output
2 1 2 3 3 4 5 -1 0
(LL会对它有影响???我气。)
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
using namespace std;
int a[200200];
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
if(a[n-1]>a[n])//因为xyz三个索引只能变换到n-2前面的数,但是a[n-1],a[n]表示就是已经完全固定了,一旦出现降序,改也改变不了
{
cout<<"-1"<<endl;//所以当a[n-1]都会比a[n]更大的时候,那么就是错的,直接输出
continue;
}
else if(a[n]>=0)//如果最大的那个都是非负数的话,那么无论怎样进行-的变化,前面的数字都会更小,形成不完全递增,所以一定会有答案
{
cout<<n-2<<endl;
for(int i=1;i<=n-2;i++)
cout<<i<<" "<<n-1<<" "<<n<<endl;
continue;
}
else
{
bool flag=true;//遍历一遍数组中是否存在递减区间,有就不行,因为这里的a[n]已经<0了,再继续往下-的去就会更加大了!
for(int i=2;i<=n;i++)
{
if(a[i-1]>a[i])
{
flag=false;
break;
}
}
if(flag==true) cout<<"0"<<endl; //if(is_sorted(a+1,a+1+n)==true)
else cout<<"-1"<<endl;
}
}
return 0;
}
is_sorted()用法:检查数组或者向量是否被排序(升序)好,是true,不是false。
此函数专门用于判断某个序列是否为有序序列。