A 困难数学题
一个数异或其本身就是0,直接输出0就好
B 构造序列
正负数要相邻,那最长的序列肯定是数量最多的数放第一个,例3a2b ,a baba,ba为一组,最后结果为少的数的两倍+最开始的那个数,特判两数相等情况
点击查看代码
ll a, b;
cin >> a >> b;
if (a < b)
{
swap(a, b);
}
if (a == b)
{
cout << a + b;
return 0;
}
cout << b + b + 1;
思路是开四个数组分别存对于每个x的最大最小y和对于每个y的最大x和最小x,只要对于每个x或y其对应的最大最小值不相等,就代表这条线有两个点,进行计算,反之不行
点击查看代码
/* 台州第一深情 */
#include <bits/stdc++.h>
using namespace std;
using i64 = long;
using ll = long long;
typedef pair<int, int> PII;
const int N = 1e6 + 5;
int a[N]; // 最小y
int b[N];
int a1[N]; // 最大y
int b1[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
a[i] = INT_MAX;//最小值初始化为最大INT,最大值初始化为0
b[i] = INT_MAX;
}
for (int i = 1; i <= m; i++)
{
int x, y;
cin >> x >> y;
a[x] = min(a[x], y);//更新对于每个x的最小y值
b[y] = min(b[y], x);
a1[x] = max(a1[x], y);//对于每个x的最大y值
b1[y] = max(b1[y], x);
}
int max1 = 0;
for (int i = 1; i <= n; i++)
{
if (a1[i] != a[i])//如果最小值跟最大值不相等则代表这跟轴上至少有两个点可以连成线,更新答案
{
max1 = max(max1, a1[i] - a[i]);
}
if (b1[i] != b[i])
{
max1 = max(max1, b1[i] - b[i]);
}
}
cout << max1;
return 0;
}
注:表示的是n以内的任何一个整数。
思路:先对整个数列进行排序,当多举几个例子会发现,前面i-1的数加起来+1小于等于i的数,那小于等于i的数则可以用前i-1的数凑,而对于i之后的数则可以用i来凑,所以最大组成应该是i的数加上前面所有数的和。例如1 1 2 5,会发现,当加到5的时候,和为4,而对于5之前的数都可以表示出来,5则可以用5单独表示,而且对于所有数之和也就是9以内的数都可以凑出来。
点击查看代码
/* 台州第一深情 */
#include <bits/stdc++.h>
using namespace std;
using i64 = long;
using ll = long long;
typedef pair<int, int> PII;
const int N = 2e5 + 5;
//1 2 3 5 10
// 1 2 4
//1 1 2 2 4 10
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
ll a[N];
for(int i = 0; i < n; i++){
cin >> a[i];
}
sort(a+0, a+n);
ll now = 1;//now表示的是当前无法被表示的最小值
for(int i = 0; i < n; i++){
if(a[i] > now){//如果a[i]大于now,说明a【i】对于组成now没有帮助,而因为now是i之前的所有数之和+1,所有now无法被表示
break;
}
now += a[i];重新更新now为前面所有a【i】和+1
}
if(now > n)//因为只要n以内的,所以只跟n比较(因为没看到n,wa了好几次)
cout << "Cool!" << '\n';
else
cout << now << '\n';因为now定义为1,所以如果无法被表示,那now就是无法被表示的最小值
}
return 0;
}