1 动态密码
思路:可以直接填空也可以写程序
void solve()
{
int a = 20241111;
stack<int> stk;
while(a)
{
stk.push(a % 2);
a /= 2;
}
while(stk.size())
{
cout << stk.top();
stk.pop();
}
}
2 购物车里的宝贝
思路:总体异或和为0即可说明可分成一样的两组
int n;
int ans;
void solve()
{
cin >> n;
int x;
for (int i = 1;i <= n;i ++) cin >> x,ans ^= x;
cout << (ans == 0 ? "YES" : "NO") << endl;
}
4 蓝桥商场
思路:ans累加最大的数需要的步骤数的同时,依次减去小的步骤
考虑:我们考虑先吃完大的食物,在本该休息的时间去吃小的食物
将以上的考虑简单化:将食品升序排列,i指向最小的食物,j指向最大的食物,tmp代表只吃这份食物所需要的时间T1(中间休息),ans累加tmp,2*a[i] - 1是吃小的食物所需的时间T2,如果T2 <= T1,则说明可以在吃大分食物的同时吃掉小份食物,如果小份以及吃完再去吃下一个小份食物
const int N = 1e5 + 9;
int n;
LL ans;
int a[N];
void solve()
{
// 30201 2*n - 1
// 2 2 2 (6)
// 3 3 3
cin >> n;
for (int i = 1;i <= n;i ++) cin >> a[i];
sort(a + 1,a + 1 + n);
for (int i = 1,j = n;i <= j;j--)
{
// cout << j << "-" << endl;
LL tmp = 2 * a[j] - 1;
ans += tmp;
while(2 * a[i] - 1 <= tmp)
{
tmp -= 2 * a[i] - 1;
i ++;
}
}
cout << ans << endl;
}
6 薅羊毛
思路:相邻两个数的gcd为1,相邻两个数的幂的gcd也为1
const int p = 1e9 + 7;
LL L,R;
LL qmi(LL a,LL b)
{
LL ans = 1;
while(b)
{
if (b & 1) ans = ans * a % p;
a = a * a % p;b >>= 1;
}
return ans;
}
void solve()
{
cin >> L >> R;
LL ans = 0;
for (int i = L;i < R;i ++)
{
LL a = qmi(i,i);
LL b = qmi(i + 1,i + 1);
LL val = (a * b % p) ;
ans = (ans + val) % p;
}
cout << ans << endl;
}
3 代金券 ※
参考的大佬的题解,意外发现了两个有趣的函数
题目大意:给定n,m,在n的开头、中间或尾部插入0~9中一个数字,满足插入后的数字仍为m的倍数,求插入后的数字的最小值
本题涉及两个有趣的函数
to_string(int or long long ),返回一个封装好对应数字的字符串
stoll(字符串),返回一个long long数
int n,m;
void solve()
{
cin >> n >> m;
string s = to_string(n);
LL mi = 2e18;
for (int i = 0;i <= s.size();i ++)//位置
{
for (int j = i == 0;j <= 9;j ++)//枚举0~9,不能头插0
{
LL tmp = stoll(s.substr(0,i) + (char)('0' + j) + s.substr(i));
if (tmp % m == 0)
mi = min(mi,tmp);
}
}
cout << (mi == 2e18 ? -1 : mi) << endl;
}
5 蓝桥派对 ※
参考大佬的题解,给出了自己的理解
实在不好理解的,列出a,b数组和所有游戏摊位结合代码,有奇效
typedef pair<int,int> PII;
const int N = 2e5 + 9;
int n,m;
int a[N],b[N];
vector<PII> v;
void solve()
{
cin >> n >> m;
for (int i = 0;i < n;i ++)
{
cin >> a[i] >> b[i];
v.push_back({a[i],b[i]});
}
sort(a,a + n);
sort(b,b + n);
for (int i = 0;i < n;i ++)
{
int l = v[i].fi,r = v[i].se;
//利用upper_bound和lower_bound的性质
int cntR = upper_bound(a,a + n,r) - a; //结束点前有多少已经开始的人(包括自己)
int cntL = lower_bound(b,b + n,l) - b; //开始点前有多少已经结束的人(不包括自己)
cout << cntR - cntL - 1 << endl; //减去自己
}
}