目录
题目一:360
小丽的动手能力很强。一天,她仅靠自己造了一台计算器。不过,这台计算器的功能还不算很强大,仅仅可以计算n个数的极差、另外,由于内存和容量限制,如果数字太多的话会删掉一些数字再进行计算。具体来说,这台计算器有三种功能:
1.新存入一个数字x;
2.输入两个数m,x,之后计算器中删除m个数字x。如果当前计算器存入的x的个数不足m,则把x全部删完;
3.计算目前计算器中存入的所有数字的极差(最大值减最小值)
现在,小丽执行了Q次操作,她想知道每次查询极差时的输出是多少。
输入描述:
由于输入可能会很多,故本题采用随机数生成器的方式生成数据,具体如下:输入仅一行两个正整数Q,seed、其中Q是操作次数,seed是一个32位无符号整型的随机种子,之后每次询问执行如下的代码产生:
unsigned seed;
function generate query() {
seed = seed ^ (seed << 15);
seed = seed ^ (seed >> 5);
seed = seed ^(seed << 1);
seed = seed %(1 << 15);
int op =(seed ^(seed << 7)^(seed >> 5)) % 3 + 1;
int m = (seed ^ (seed << 6)^(seed >> 10) % Q+ 1;
int x=(seed ^(seed <<5)^(seed <<9)^(seed >> 6))% 10 + 1;return lop, m, x];
上述提供的伪代码并不能直接在IDE中运行,需要根据您作答的语言进行对应调整后再使用其中^表示异或,%表示取模,《《是左移,>>是右移。
如果op=1,则表示存入一个数字x(此时m虽生成但无用);如果op=2,则表示第二个操作:删除m个数字x;如果op=3,则表示查询存入的所有数字的极差。数据保证此时计算器内至少存有一个数字(此时m,x虽生成但无用)。
对于100%的数据,1≤Q≤2x1050≤seed<2的15次方
输出描述:
由于输出可能会很多,输出格式如下:设-开始ans=0。设当前是第;次操作,如果是操作3,求得的极差为x,那么给ans异或上ix。最后输出ans。
样例输入:
8 234
样例输出:
42
样例分析:
样例对应的操作如下:
插入数字8[1,2,8]
[2,1,7]删除1次数字7
[3,7,8]
查询极差,此时极差为0,ans=ans(0x3)=0
插入数字2[1,2,2]
删除5次数字1[2,5,1]
[2,1,10]删除1次数字10
[3,7,9]查询极差,此时极差为6,ans=ansФ(6x7)=42
[2,1,2] 删除1次数字2
故最后ans=42。
#include <iostream>
#include <vector>
using namespace std;
unsigned seed;
int Q;
int generateOp() {
seed = seed ^ (seed << 15);
seed = seed ^ (seed >> 5);
seed = seed ^ (seed << 1);
seed = seed % (1 << 15);
int op = (seed ^ (seed << 7) ^ (seed >> 5)) % 3 + 1;
return op;
}
int generateM() {
int m = (seed ^ (seed << 6) ^ (seed >> 10)) % Q + 1;
return m;
}
int generateX() {
int x = (seed ^ (seed << 5) ^ (seed << 9) ^ (seed >> 6)) % 10 + 1;
return x;
}
int calculateJichai(const vector<int>& numbers) {
int minVal = INT_MAX;
int maxVal = INT_MIN;
for (int num : numbers) {
minVal = min(minVal, num);
maxVal = max(maxVal, num);
}
return maxVal - minVal;
}
int main() {
cin >> Q >> seed;
vector<int> numbers;
int ans = 0;
for (int i = 1; i <= Q; i++) {
int op = generateOp();
int m = generateM();
int x = generateX();
if (op == 1) {
numbers.push_back(x);
}
else if (op == 2) {
for (int j = 0; j < m; j++) {
numbers.erase(remove(numbers.begin(), numbers.end(), x), numbers.end());
}
}
else if (op == 3) {
int jichai = calculateJichai(numbers);
ans ^= (i * jichai);
}
}
cout << ans << endl;
return 0;
}
题目二:360
小明非常喜欢吃美食,同时他非常讨厌吃到重复的东西。小云为小明准备了n道美食,其中第i道美食的特征值为a;,因为小明讨厌重复的东西,所以小云想通过混合美食来改变其特征值使得所有美食特征值互不相同。具体的小云每次可以选择两个特征值分别为x,y的美食并将x加入y中变成特征值为x和x+y的美食,现在小云想知道他最少需要混合多少次使得所有美食特征值互不相同。
输入描述
第一行一个正整数n接下来一行n个数字分别表示每个美食的特征值对于所有的数据,n<=100000保证 1≤a;≤ n。
输出描述
输出一个非负整数表示最小混合的次数
样例输入
6
1 4 1 3 5 5
样例输出
2
样例解释
小云可以先将特征值为 5,1的美食混合得到5,6。再将特征值为6,5的美食混合得到6,11,此时所有美食特征值分别为1,4,6,3,5,11。可以证明没有次数更少的方案。
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int minMixingTimes(const vector<int>& features) {
unordered_map<int, int> count;
int minMixingTimes = 0;
for (int feature : features) {
count[feature]++;
}
for (auto it = count.begin(); it != count.end(); ++it) {
int feature = it->first;
int frequency = it->second;
while (frequency > 1) {
int newFeature = feature;
while (count.find(newFeature) != count.end()) {
newFeature += feature;
}
count[newFeature]++;
minMixingTimes++;
frequency--;
}
}
题目三:美团
假设美团的工号是由18位数字组成的,由以下规则组成:
。前面6位代表是哪个部门
。7-14位代表是出生日期,范围是1900.01.01-2023.12.31
。15-17位代表是哪个组,不能是完全一样的3位数字
。18位是一位的校验和,假设是,则需要满足(x+a1+a2 +a3 +a4+...+a17)mod 8=1,a1-a17 代表了前面的17位数字现在需要写一份代码,判断输入的工号是否符合对应的规则。
提示:
出生日期这里需要判断闰年。闰年判断的条件是能被4整除,但不能被 100 整除;或能被 400 整除。
输入描述:
第一行输入一个整数n(1 < n≤ 10)
接下来n行,每行输入一个字符串,表示一个合法的部门。如果工号不属于合法部门的话,则认为这个工号不符合规则。
接下来输入一个整数m(1 < m < 10)
接下来m行,每行输入一个字符串,表示需要验证的工号。
输出描述:
如果不满足上述任一个规则,输出"error",都满足的话输出"ok"
样例1输入:
2
123456
123457
1
123456202312120636
样例1输出:
ok
样例2输入:
1
123455
1
123456202312120633
样例2输出:
error
说明:
部门号不对
样例3输入:
1
123456
2
123456202313120633
123456202302290633
样例3输出:
error
error
说明:
出生日期不对
2023不是闰年,没有29号
样例4输入:
1
123456
1
123456202312120635
样例4输出:
error
说明:
校验码不对
#include<bits/stdc++.h>
using namespace std;
bool isLeapYear(int year)
{
return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}
bool isValidDate(int yr ,int mth, int day)
{
if(yr < 0 || mth < 1 || mth > 12 || day < 1)
return false;
int dim;
switch(mth)
{
case 1:case 3:case 5:case 7:case 8:case 10:case12:
dim = 31;
break;
case 4:case 6:case 9:case 11:
dim =30;
break;
case 2:
dim = (isLeapYear(yr) ? 29:28);
break;
default:
return false;
}
return day <= dim;
}
int main()
{
ios::sync_with_stdio(false);
std::cin.tie(0);
set<string> se;
int n; cin>>n;
for(int i=0; i<n; i++)
{
string t;
cin >> t;
se.insert(t);
}
int m;
cin >> m;
while(m--)
{
string s;
cin >> s;
string num = s.substr(0,6);
string bi = s.substr(6,8);
string group = s.substr(14,3);
int x = s.back()- '0';
int su = x;
for(int i = 0; i<17; i++)
{
su = (su + s[i] - '0') % 8;
}
if(!se.count(num))
{
cout<<"error\n";
continue;
}
if(su != 1)
{
cout<<"error\n";
continue;
}
int year = stoi(bi.substr(0,4));
int month = stoi(bi.substr(4,2));
int day = stoi(bi.substr(6,2));
if(year < 1900 || year > 2023)
{
cout<<"error\n";
continue;
}
if(!isValidDate(year,month,day))
{
cout<<"error\n";
continue;
}
cout<<"ok\n";
}
}
题目四:美团
小美拿到了一个由正整数组成的数组,但其中有一些元素是末知的(用0来表示)现在小美想知道,如果那些未知的元素在区间,,范围内随机取值的话,数组所有元素之和的最小值和最大值分别是多少?
共有q次询问
输入描述:
第一行输入两个正整数n,q,代表数组大小和询问次数。
第二行输入n个整数ai;,其中如果输入的ai为0,那么说明ai是末知的。
接下来的q行,每行输入两个正整数 l,r,代表一次询问。
1 ≤ n,q ≤ 10的5次方
0 ≤ ai ≤ 10的9次方
1 ≤ l ≤ r ≤ 10的9次方
输出描述:
输出q行,每行输出两个正整数,代表所有元素之和的最小值和最大值。
示例1输入:
3 2
1 0 3
1 2
4 4
示例1输出:
5 6
8 8
说明:
只有第二个元素是末知的。
第一次询问,数组最小的和是 1+1=3=5,最大的和是 1+2+3=6。
第二次询问,显然数组的元素和必然为8.
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main ()
{
ios::sync with stdio(false);
std::cin.tie(0);
LL res = 0;
int n,q;
cin >>n >> q;
vector<LL> a(n);
LL sum =0;
LL cnt = 0;
for(int i=0; i<n; i ++)
{
cin >> a[i];
if(a[i])
sum += ali];
else
cnt++;
}
while(q --)
{
LL l,r;
cin >> l>> r;
cout << sum + l * cnt <<" "<< sum + r * cnt << "\n";
}
return 0;
}