A. Prison Break
题目链接
https://codeforces.com/contest/1484/problem/A
题目大意
没读题,猜的 a*b
解题思路
同上
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin >> t;
while(t--){
int a,b;
cin >> a >> b;
cout << a * b << "\n";
}
return 0;
}
B. Restore Modulo
题目链接
https://codeforces.com/contest/1484/problem/B
题目大意
由n, m, c, s四个数生成一个序列(a1,a2,a3…an),其中:
- a1=s % m
- ai=(ai−1+c) % m ,1 < i <= n
现在给你这样的序列a1,a2,…,an,判定是否存在可以生成这个序列的n, m, c, s。
如果存在,请使m最大。
解题思路 反证法
有题目可知,如果序列是由某个n,m,c,s生成,那就假设成立,则该序列必然满足下述条件:
- a1=s % m
- ai=(ai−1+c) % m ,1 < i <= n
进一步我们可以发现:
(1)当ai-1+c < m时,ai-1+c = ai
(2)当ai-1+c > m时,(ai-1+c) % m = ai
(3)序列a中的最大值maxx 必然小于 m (每一项都%m)
(4)序列a中的最大值maxx 和maxx的下一项anext 满足 (maxx + c) % m = anext,即maxx + c > m,从而 m = maxx + c - anext
【maxx已是最大值,anext只能小于maxx,即使anext不存在,根据假设,也可以由序列推导出来】
由上,我们可以扩展得到:
- maxx < m < maxx + c
- 当ai<ai+1时,ai + c = ai+1
- 当ai>aI+1时,(ai + c)% m = ai+1,ai+ c - ai+1 = m
很显然,当上述条件满足时,c是一个固定值,m也是一个固定值,序列元素间的差值非常关键。
进一步分析:
(1)显然,单调递增或者递减的等差序列,如1 3 5 7,c固定,但存在无数个满足条件的m。
(2)排除(1)(3)情况,如果序列元素可以由n,m,c,s生成,则序列元素间的差值存在两种情况,否则不存在n,m,c,s:
当ai<ai+1时,ai + c = ai+1,c = ai+1 - ai
当ai>aI+1时,ai+ c - ai+1 = m ,c - m = ai+1 - ai
差值1 = c > 0,差值2 = c - m < 0,两个差值中最大的即是 c
由于c - m < 0,所以 m = c + - ( c - m),且满足 maxx < m < maxx + c
(3)序列元素间的差值如果都为0,显然存在无数种情况。
代码如下
#include<bits/stdc++.h>
using namespace std;
#define test 0
#define pb push_back
#define mp make_pair
const int N = 1e5 + 10;
int a[N],b[N];
set<int> s;
void sss(){
s.clear();
int n;
cin >> n;
int maxx = -1;
for(int i = 0;i < n;i++){
scanf("%d",&a[i]);
maxx = max(maxx,a[i]);
}
for(int i = 1;i < n;i++){
s.insert(a[i] - a[i - 1]);
}
if(s.size() == 0){
cout << "0\n";
return ;
}
if(s.size() == 1){
cout << "0\n";
return ;
}
if(s.size() == 2){
int all = 0;
int c = 0;
for(auto it : s){
all += abs(it);
c = max(c,it);
}
if(all < maxx){
cout << "-1\n";
return ;
}else{
cout << all << " " << c << "\n";
return ;
}
}else{
cout << "-1\n";
return ;
}
}
int main(){
if(test)
freopen("x.txt","r",stdin);
int t;
cin >> t;
while(t--){
sss();
}
return 0;
}
C. Basic Diplomacy
题目链接
https://codeforces.com/contest/1484/problem/C
题目大意
4 6
1 1
2 1 2
3 1 2 3
4 1 2 3 4
2 2 3
1 3
A计划打n = 6天游戏,需要朋友一块玩,有m = 4位朋友。
每天只有一些朋友有空。如第三天,只有1 2 3有空。
要求每位朋友一起玩的次数不超过 次
判定是否有解。
解题思路 贪心
将每天的人选存入一个二维vector中,然后从可选择的人数最小的vector开始,每次选取已玩耍次数最低的人,最后判定出现次数最多的人是否满足限制。
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
const int N = 1e5 + 5;
int f[N];
vector<vector<int> > v;
vector<int> res;
bool cmp(vector<int> a,vector<int> b){
return a.size() < b.size();
}
void sss(){
int n,m;
cin >> n >> m;
int maxx = 0;
v.clear();
res.resize(m);
for(int i = 0;i < N;i++) f[i] = 0;
int p = ceil( 1.0 * m / 2.0);
for(int i = 0;i < m;i++){
int x,y;
cin >> x;
vector<int> vv;
vv.pb(i);//记录坐标
for(int j = 1;j <= x;j++){
cin >> y;
vv.pb(y);
}
v.pb(vv);
}
sort(v.begin(),v.end(),cmp);
for(int i = 0;i < m;i++){
int sz = v[i].size();
int num = v[i][1];
for(int j = 1;j < sz;j++){
if(f[num] > f[v[i][j]]){
num = v[i][j];
}
}
f[num]++;
res[v[i][0]] = num;//按坐标对应记录num
maxx = max(maxx,f[num]);
}
if(maxx > p){
cout << "NO\n";
return ;
}else{
cout << "YES\n";
for(auto it:res){
cout << it << " ";
}
cout << "\n";
return ;
}
}
int main(){
//freopen("x.txt","r",stdin);
int t;
cin >> t;
while(t--){
sss();
}
return 0;
}