题目大意:
给你
x
,
y
,
n
x,y,n
x,y,n,要你在
[
1
,
n
]
[1,n]
[1,n]内找到最大
n
u
m
num
num的数满足
n
u
m
num
num %
x
=
y
x=y
x=y。
思路:
一开始想的枚举
x
x
x的倍数,然后超时了,就只能往数学的方向思考了,满足要求的最大的数一定是分布的
n
n
n那里,所以我们可以直接
n
−
(
n
n-(n
n−(n%
x
)
+
y
x)+y
x)+y就行了,意思是用
n
n
n减去超过
x
x
x的那一部分,那么剩下的一定%
x
=
0
x=0
x=0,所以再加上
y
y
y就行了,不过有可能
n
−
(
n
n-(n
n−(n%
x
)
+
y
x)+y
x)+y会
>
n
>n
>n,所以对于
>
n
>n
>n只需要多减去一个
x
x
x即可。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
void solved(){
ll x,y,n;cin>>x>>y>>n;
if(n % x == y){
cout<<n<<endl;
}else{
if(n - (n % x) + y <= n)
cout<<n - (n % x) + y<<endl;
else cout<<n - (n % x) - x + y<<endl;
}
}
int main(){
int t;cin>>t;
while(t--)
solved();
return 0;
}
题目大意:
给你一个数
n
n
n,对于这个数你可以选择两种操作,那么对它
∗
2
*2
∗2,要么
/
6
/6
/6(必须整除),问你从
n
n
n到
1
1
1最少操作步数是多少,如果不能得到
1
1
1输出
−
1
-1
−1。
思路:
这个题往数学想了一会,发现没什么思路,然后注意到
n
=
1
e
9
n=1e9
n=1e9,然后每次
∗
2
o
r
/
6
*2 o r/6
∗2or/6,时间复杂度是
O
(
l
o
g
n
)
O(logn)
O(logn),所以模拟写了一发暴力
a
c
ac
ac.
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
void solved(){
ll x;cin>>x;
int cnt = 0;
while(x != 1){
if(x >= 1e9){
cout<<"-1"<<endl;return ;
}
if(x % 6 == 0)x /= 6;
else x *= 2;
cnt++;
}
cout<<cnt<<endl;
}
int main(){
int t;cin>>t;
while(t--)solved();
return 0;
}
题目大意:
给你一个字符串,问你将一个字符串变成好的字符串最少需要多少操作,好的字符串是
t
=
"
(
)
"
t="()"
t="()",如果
a
,
b
a,b
a,b是好的字符串那么
a
+
b
或
者
(
a
)
a+b或者(a)
a+b或者(a)也都是好的字符串,你可以选择
i
,
1
<
=
i
<
=
n
i,1<=i<=n
i,1<=i<=n,然后把
s
[
i
]
s[i]
s[i]插入字符串头部或者尾部。
思路:
看到括号就会想到栈,用栈模拟一下就行了,如果栈空切
s
[
i
]
=
′
)
′
s[i]=')'
s[i]=′)′则说明操作次数+1,因为你要把这个括号自动后面去,如果栈不空且
s
[
i
]
=
′
)
′
s[i]=')'
s[i]=′)′说明匹配,
p
o
p
pop
pop一下,否则入栈。
代码:
#include<bits/stdc++.h>
using namespace std;
void solved(){
int n;cin>>n;
string s;cin>>s;
stack<char>st;
int cnt = 0;
for(int i = 0; i < s.size(); i++){
if(st.empty() && s[i] == ')'){
cnt++;continue;
}
if(!st.empty() && s[i] == ')'){
st.pop();continue;
}
st.push(s[i]);
}
cout<<cnt<<endl;
}
int main(){
int t;cin>>t;
while(t--)solved();
return 0;
}
题目大意:
给你一个长度为
n
n
n的数组和一个整数
k
k
k,问你将数组所有元素都能够被
k
k
k整除,需要操作最少的次数是多少?你有两种操作,第一个是给数组某个元素
+
x
(
x
+x(x
+x(x一开始为0),然后
x
+
=
1
x+=1
x+=1,第二种操作是
x
+
=
1
x+=1
x+=1。
思路:
用对每个数
a
[
i
]
=
k
−
a
[
i
]
a[i] = k - a[i]
a[i]=k−a[i] %
k
k
k,求一下每个数能被
k
k
k整除还需要多少步骤,一开始写了一个玄学优先队列,最终弃疗了,加入
a
[
]
=
1
,
2
,
3
,
4
,
5
a[]={1,2,3,4,5}
a[]=1,2,3,4,5其实我们只需要输出5就行了,因为在之前的数可以分配给小的数,也就说答案就是
m
a
x
(
a
i
)
max(ai)
max(ai),但是有可能有多少相同的数,例如
a
[
]
=
1
,
1
,
1
,
2
,
2
,
2
,
2
,
2
,
4
,
5
,
6
,
8
a[]={1,1,1,2,2,2,2,2,4,5,6,8}
a[]=1,1,1,2,2,2,2,2,4,5,6,8那么这个时候
m
a
x
(
a
i
)
max(ai)
max(ai)显然不是答案,因为要满足
2
2
2,
x
x
x需要多跑几个来回(在modk意义下),那么容易发现答案就是出现次数最多的那个数,它的操作次数为
a
[
i
]
+
k
∗
(
n
u
m
i
−
1
)
,
n
u
m
i
a[i]+ k * (numi - 1),numi
a[i]+k∗(numi−1),numi是最多出现的那个数的次数,把这两种清空整合在一起取一个
m
a
x
max
max就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
typedef long long int ll;
ll n,k,x;
ll a[maxn];
int cmp(int a,int b){
return a > b;
}
void solved() {
ll n,k;cin>>n>>k;
for(int i = 1; i <= n; i++){
cin>>a[i];
if(a[i] % k == 0)a[i] = 0;
else a[i] = k - a[i] % k;
}
sort(a + 1, a + 1 + n,cmp);
ll ans = 0;
for(int i = 1; i <= n; i++){
if(a[i] == 0){
if(i == 1){
cout<<"0"<<endl;return ;
}
break;
}
if(a[i] != a[i + 1]){
ans = max(ans,a[i]);
}else{
ll cnt = 0;
while(i + 1 <= n && a[i] == a[i + 1])
i++,cnt++;
ans = max(k * cnt + a[i],ans);
}
}
cout<<ans + 1<<endl;
}
int main() {
int t;cin>>t;
while(t--)solved();
return 0;
}
题目大意:
有两个人,有
n
n
n本书,每本书有
(
t
,
a
,
b
)
(t,a,b)
(t,a,b),
t
t
t表示看完这本书需要的时间,
a
=
1
a=1
a=1表示第一个人可以选,
b
=
1
b=1
b=1表示第二个人可以选,如果
a
,
b
a,b
a,b同时为一表示他们都可以同时看,问你每个人看完
k
k
k本书的最少时间。
思路:
很显然是贪心,关键是怎么贪,我们可以将这些书分成四类。
第一类:两人都可以看
第二类:只有第一个人可以看
第三类:只有第二个人可以看
第四类:两人都不可以看
第四类可以不用考虑,我们先对第一,二类升序排序,然后同时加入第一类,这样可以保证第一个人读最优的书的同时保证第二个人也是最优,然后再对第三类升序选择前
k
k
k个就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
void solved(){
int n,k;cin>>n>>k;
vector<int>all;
vector<int>a;
vector<int>b;
for(int i = 1; i <= n; i++){
int t,x,y;
cin>>t>>x>>y;
if(x == 1 && y == 1){
all.push_back(t);
}else if(x == 1){
a.push_back(t);
}else if(y == 1){
b.push_back(t);
}
}
sort(a.begin(),a.end());
sort(b.begin(),b.end());
for(int i = 0; i < min(a.size(),b.size()); i++){
all.push_back(a[i] + b[i]);
}
if(all.size() < k){
cout<<"-1"<<endl;return ;
}
sort(all.begin(),all.end());
int ans = 0;
for(int i = 0; i < k; i++){
ans += all[i];
}
cout<<ans<<endl;
}
int main(){
solved();
return 0;
}