目录
前言
我把权游第4季看完都没想明白这个问题到底是啥意思。
随着人工智能的发展,在技术对人类本身的监控方面有哪些(建议字数:300字以上)
虽然我语文不是很行,但是也没到看不懂中文题目的程度:
虽然最后瞎编了一堆话交了上去,但是我还是对这个题的题意表示很纠结。
8说了,上主菜。
A - Nearest Interesting Number(暴力+水题)
比赛链接:https://codeforces.com/problemset/problem/1183/A
题目大意
给你一个数 x x x,找出离 x x x最近的一个数 y y y满足:
1. y > = x 1.y>=x 1.y>=x;
2. y 的 每 个 数 位 之 和 可 以 整 除 4 2.y的每个数位之和可以整除4 2.y的每个数位之和可以整除4;
思路
从 x x x开始暴力所有的数,直到遇到一个满足条件的数为止。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=55000;
int main()
{
int n;
cin>>n;
while(true){
int m=n;
int sum=0;
while(m){
sum+=m%10;
m/=10;
}
if(sum%4==0){
cout<<n<<endl;
break;
}
n++;
}
}
B - Equalize Prices (思维)
比赛链接:https://codeforces.com/problemset/problem/1183/B
题目大意
现在给你一个长度为 n n n的数组 a a a。
你可以把数组 a a a中的任意一个数 a i a_i ai变成[ a i − k , a i + k a_i-k,a_i+k ai−k,ai+k]中的任意一个数字。但每个数字只能改一次。
例如 a i = 4 a_i=4 ai=4, k = 3 k=3 k=3,则 a i a_i ai可以改为 1 1 1~ 7 7 7中的任意一个数字。
现在问,你现在可不可以把数组 a a a中的所有数字改成同一个数字 B B B?
不能就输出 − 1 -1 −1,如果能则输出 B B B的最大值。
思路
一个很简单的思维题。
首先我们先想最简单的:数字 B B B存不存在?
我们只需要找到数组中最大的数 m a x x maxx maxx和数组中最小的数 m i n x minx minx。
m i n x minx minx最大可以变成 m i n x + k minx+k minx+k, m a x x maxx maxx最小可以变成 m a x x − k maxx-k maxx−k.
如果此时最小的最大还是小于最大的最小,那么 B B B就肯定不存在了,输出 − 1 -1 −1;否则就存在 B B B。
那么最大的 B B B是多少呢?
是 m i n x + k minx+k minx+k。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=150;
int a[maxn];
int main()
{
int q,n,k;
cin>>q;
while(q--)
{
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
if(a[0]+k>=a[n-1]-k) cout<<a[0]+k<<endl;
else cout<<"-1"<<endl;
}
}
C - Computer Game (思维)
比赛链接:https://codeforces.com/problemset/problem/1183/C
题目大意
宿舍断电了, V o v a Vova Vova的电脑还有 k k% k的电量,但是他刚入手了一款非常好玩的游戏,于是他决定上号玩一把。
这个游戏有 n n n个关卡, V o v a Vova Vova作为一个游戏高手自然想要玩通关。关卡分为两种: a 和 b a和b a和b。
1.当 V o v a Vova Vova的电脑电量严格大于 a a a时,他可以玩一把 a a a类型的关卡,此时电量会减少 a a a;
2.当 V o v a Vova Vova的电脑电量严格大于 b ( b < a ) b(b<a) b(b<a)时,他可以玩一把 b b b类型的关卡,此时电量会减少 b b b;
3.当 V o v a Vova Vova的电脑电量小于 b b b时,他就没法玩游戏了。
V o v a Vova Vova想知道他能否在电脑歇菜之前通关这个游戏,不能输出 − 1 -1 −1。
如果可以, V o v a Vova Vova想知道他最多能玩几场 a a a类型的关卡,输出这个数量。
思路
彼时彼刻,恰如此时此刻,宿舍断电了,有点裂开。
一道有点难度的思维题,推了好一会才出的答案。
首先还是先判断最简单的:
从题目中可以看出 b < a b<a b<a,那么我们就看如果我们玩 n n n场 b b b类型的关卡电脑能否撑得住。
玩n场b类型的关卡需要的电量为 n ∗ b n*b n∗b,电脑电量为 k k k,则根据题目描述: n ∗ b < k n*b<k n∗b<k
接下来我们设可以玩 x 1 x_1 x1场 a a a类型的关卡, x 2 x_2 x2场 b b b类型的关卡,则有公式:
x 1 + x 2 = n x_1+x_2=n x1+x2=n
x 1 ∗ a + x 2 ∗ b < k x_1*a+x_2*b<k x1∗a+x2∗b<k
此时再根据 a > b a>b a>b可以推得:
x 1 ∗ ( a − b ) + ( x 1 + x 2 ) ∗ b < k x_1*(a-b)+(x_1+x_2)*b<k x1∗(a−b)+(x1+x2)∗b<k
再结合 x 1 + x 2 = n x_1+x_2=n x1+x2=n,再次化简:
x 1 ∗ ( a − b ) + n ∗ b < k x_1*(a-b)+n*b<k x1∗(a−b)+n∗b<k
x 1 < k − ( n ∗ b ) ( a − b ) x_1<\frac{k-(n*b)}{(a-b)} x1<(a−b)k−(n∗b)
再利用C语言中的 / / /是向下取整,所以 x 1 = k − ( n ∗ b ) ( a − b ) x_1=\frac{k-(n*b)}{(a-b)} x1=(a−b)k−(n∗b)。
不过还有一个点:当 k − ( n ∗ b ) k-(n*b) k−(n∗b)可以整除 ( a − b ) (a-b) (a−b)时,代表电量是正好够的.
但实际上是没法完成的,因为你的用电量是要严格大于 k k k的,所以此时我们需要少玩一局 a a a类型的关卡( x 1 − − x_1-- x1−−)。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=150;
int main()
{
int t;
cin>>t;
while(t--)
{
ll k,n,a,b;
cin>>k>>n>>a>>b;
if(k<=n*b) cout<<"-1"<<endl;
else
{
ll x=(k-n*b)/(a-b);
if((k-n*b)%(a-b)==0) x--;
cout<<min(n,x)<<endl;
}
}
}
D - Candy Box (easy version) (魔鬼题+贪心)
比赛链接:https://codeforces.com/problemset/problem/1183/D
题目大意
你现在有 n n n个糖果,第 i i i个糖果的种类是 a i a_i ai。
现在你想拿着你的糖果去送人。
你不喜欢把糖果混在一起,所以你都只给每个人一种不同于其他人的糖果。
你希望送给每个人的糖果的数量都不同,你现在想知道你最多能送出多少糖果。
思路
这个题的时间复杂度很魔鬼,给了 3 s 3s 3s,却在那里卡死你的memset
,只要用这个初始化数组就会 T T T。
很简单的一道贪心题。
我们先把所有糖果按照种类统计一下:
for(int i=0;i<=n;i++)
a[i]=0; //a[i]:种类为i的糖果的数量
for(int i=0;i<n;i++){
int x;
cin>>x;
a[x]++;
}
接下来从大到小排个序,然后贪心模拟整个过程就可以。
每次记录上次送出的糖果数量 p r e pre pre:
如果此次要送的糖果的数量小于上次的数量 p r e pre pre,那我们就全部送出去,并更新上一次的数量 p r e pre pre;
否则我们就送 p r e − 1 pre-1 pre−1个,并更新上一次的数量 p r e pre pre;
AC代码
///memset会T
///不是3s吗?
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int a[maxn];
int main()
{
int t;
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=0;i<=n;i++)
a[i]=0;
for(int i=0;i<n;i++){
int x;
cin>>x;
a[x]++;
}
sort(a+1,a+n+1,greater<int>());
ll ans=a[1];
int pre=a[1];
for(int i=2;i<=n;i++){
if(a[i]==0) break;
if(a[i]<pre){
ans+=a[i];
pre=a[i];
}
else{
ans+=pre-1;
pre--;
}
if(pre==0) break;
//cout<<"ans="<<ans<<endl;
}
cout<<ans<<endl;
}
}
E - Subsequences (easy version) (BFS)
比赛链接:https://codeforces.com/problemset/problem/1183/E
题目大意
给一个字符串 s s s,每次你可以删除任意一个字符形成一个新串 s ′ s' s′。
问字符串 s s s是否可以生成 k k k个不同的字符串。
不可以的话输出 − 1 -1 −1,可以的话输出生成 k k k个不同的字符串最少要删除多少个字符。
思路
暴力就可以,直接写一个 B F S BFS BFS爆搜出所有结果,用 m a p map map来进行标记。
AC代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
string ss;
map<string,int> mp;
int n,k;
int bfs()
{
queue<string> q;
q.push(ss);
mp[ss]=1;
int cnt=0;
while(!q.empty()&&k){
string str=q.front();
q.pop();
k--;
cnt+=n-str.size();
for(int i=0;i<str.size();i++)
{
string s1=str.substr(0,i)+str.substr(i+1,str.size()-i-1);
if(mp[s1]==0){
mp[s1]=1;
q.push(s1);
}
}
}
if(k) return -1;
else return cnt;
}
int main()
{
cin>>n>>k;
cin>>ss;
int ans=bfs();
cout<<ans<<endl;
}
F - Topforces Strikes Back(数学+贪心)
比赛链接:https://codeforces.com/problemset/problem/1183/F
题意
给出由n个数字构成的数组a。
你可以在数组a中寻找最多三个数进行求和。
你找的数需要满足:彼此之间不能被整除。
例如,你找到了 a 、 b 、 c ( a < b < c ) a、b、c(a<b<c) a、b、c(a<b<c),则它们需要满足:c不能整除a与b,b不能整除a
。
问:这个和最大是多少?
思路
这个题稍微有些难度,但还是比较简单的。
首先看完题之后我们需要知道:原本的数组并不能直接用,需要去重(相同的数字互相整除)。
去重的方法有很多, s e t , u n i q u e set,unique set,unique等等。
我这里用的是unique,这是我之前看大佬题解时看到的一种去重,感觉很不错。
vector<ll> arr;
for(int i=1; i<=n; i++)
{
cin>>x;
arr.push_back(x);
}
sort(arr.begin(),arr.end());
arr.erase(unique(arr.begin(),arr.end()),arr.end());
接下来我们开始枚举 a a a的值。
由于是要求最大值,所以我们 a , b , c a,b,c a,b,c都是按照最大值去取。
枚举的代码是一个 O ( n 3 ) O(n^3) O(n3)的时间复杂度,但是由于每次我们都是贪心处理(即一旦找到合适的值就一定是这个 a a a能够达到的最大值,不再去考虑别的组合),所以实际上没有这么拖时间。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int main()
{
int t;
cin>>t;
while(t--)
{
ll n,x;
cin>>n;
vector<ll> arr;
for(int i=1; i<=n; i++)
{
cin>>x;
arr.push_back(x);
}
sort(arr.begin(),arr.end());
arr.erase(unique(arr.begin(),arr.end()),arr.end());
int len=arr.size();
ll ans=0;
for(int i=len-1; i>=0; i--)
{
ans=max(ans,arr[i]);
//cout<<arr[i]<<" "<<endl;
for(int j=len-1; j>i; j--)
{
if(arr[j]%arr[i])
{
ans=max(ans,arr[i]+arr[j]);
//cout<<arr[i]<<" "<<arr[j]<<" ";
for(int k=j-1; k>i; k--)
if(arr[j]%arr[k]&&arr[k]%arr[i])
{
ans=max(ans,arr[i]+arr[j]+arr[k]);
//cout<<arr[i]<<" "<<arr[j]<<" "<<arr[k]<<endl;
break;
}
break;
}
}
//cout<<endl;
}
cout<<ans<<endl;
}
}
感谢阅读,希望能对你产生一点用处。