Dashboard - Polynomial Round 2022 (Div. 1 + Div. 2, Rated, Prizes!) - Codeforces
A. Add Plus Minus Sign
题意:给定01串,在其中加(-或+)运算符,使绝对值尽可能地小。
思路:第奇数个1前面放+,偶数个前面放-,0前面(+、-)都可。
#include<bits/stdc++.h>
// #define int long long
#define PII pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cin.tie(0)
using namespace std;
const int N=2e5+10;
int n;
int a[N];
void solve(){
string s;
cin >> n;
cin >> s;
bool ok=false;
if(s[0]=='1') ok=true;
for(int i=1;i<n;i++){
if(s[i]=='1') ok=!ok;
if(ok) cout << "+";
else if(s[i]=='0') cout << "+";
else if(ok==false) cout << "-";
}
cout << endl;
}
int main(){
int t=1;
cin >> t;
while(t--){
solve();
}
}
B. Coloring
题意:给定一个长度为n的单元格,m种颜色,每种颜色有ai 个,要求将这些颜色全部涂到单元格中,且对每k个单元格中的颜色全都不同。
思路:可以将单元格分为 n/k 组 ,每组 k 个,剩下 n%k 个单独作为一组,所以每种颜色的个数不能大于 n/k+1 (NO),如果等于n/k+1,则看看 n%k 组 还有没有剩余的,有的话放进去即可,没有的话(NO),模拟完上述过程输出(YES)
#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int>
#define ios ios::sync_tith_stio(false);cin.tie(0);cin.tie(0)
using namespace std;
const int N=2e5+10;
const int inf=1e9;
int n,m,k;
int a[N];
void solve(){
cin >> n >> m >> k;
for(int i=0;i<m;i++){
cin >> a[i];
}
int num=n%k;
int res=n/k;
for(int i=0;i<m;i++){
if(a[i]>res+1){
cout << "NO" << endl;
return ;
}
if(a[i]==res+1){
num--;
if(num<0){
cout << "NO" << endl;
return ;
}
}
}
cout << "YES" << endl;
}
signed main(){
int t=1;
cin >> t;
while(t--){
solve();
}
}
C. Ice and Fire
题意:有n名玩家进行游戏,给定一个长度为n-1的01字符串。游戏规则:n个人有一个力量值(1--n 且 每个人的力量值都不同),进行n-1局游戏,每次淘汰掉其中一人,问有多少个人可能成为最后的赢家(2~n个玩家参与游戏的答案都要输出)。 进行第i局游戏时,01串为0:力量值小的获胜,1:力量值大的获胜。
思路:假设最后一位是 1,且他的前面有x个连续的1(包含最后一个),如(1011),那么对于最后两局(11),如果(1,2)还在的话,也势必会被淘汰,对于(3,4,5)可证都会有赢得可能(手动模拟一下即可知)。最后一位是0也是如此,假设有x个连续的0在末尾,那么最大的x个值必定没有赢的可能,所以进行 i 局游戏,就是看s0——si 中,后缀连续的长度,答案就是 i-后缀连续长度。
#include<bits/stdc++.h>
// #define int long long
#define PII pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cin.tie(0)
using namespace std;
const int N=2e5+10;
int n;
int a[N];
int sum[N];
void solve(){
string s;
cin >> n;
cin >> s;
s=' '+s;
int ed=-1;
int num=0;
for(int i=1;i<s.size();i++){
if(ed!=s[i]-'0'){
cout << i << " ";
ed=s[i]-'0';
num=1;
}
else{
num++;
cout << i+1-num << " ";
}
}
cout << endl;
}
int main(){
int t=1;
cin >> t;
while(t--){
solve();
}
}
D. Same Count One
题意:有n个长度为m的01串,每次可以选择其中的两个串的相同的位置,交换这两个位置上的数字,问否经过上述操作使得每个串的1的个数相等。可以的话输出每次交换操作。
思路:首先判断是否能被平分。否则,枚举每一列,如果当前位置为0且缺少1或当前位置为1且1过多,分别将其储存一下,然后将这些行尽可能的交换,模拟此过程即可。
#include<bits/stdc++.h>
// #define int long long
#define PII pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cin.tie(0)
using namespace std;
const int N=1e5+10;
int n,m;
int s[N];
struct Node{
int x,y,pos;
};
void solve(){
cin >> n >> m;
vector<vector<int>> a(n+1,vector<int>(m+1));
int num=0;
for(int i=1;i<=n;i++){
s[i]=0;
for(int j=1;j<=m;j++){
cin >> a[i][j];
if(a[i][j]==1){
num++;
s[i]++;
}
}
}
if(num%n!=0){
cout << "-1" << endl;
return ;
}
num/=n;
vector<Node> res;
vector<int> b,c;
for(int j=1;j<=m;j++){
for(int i=1;i<=n;i++){
if(a[i][j]==0 && s[i]<num) b.push_back(i); // 少1
if(a[i][j]==1 && s[i]>num) c.push_back(i); // 多1
}
for(int k=0;k<min(b.size(),c.size());k++){
s[b[k]]++,s[c[k]]--;
res.push_back({b[k],c[k],j});
}
b.clear(),c.clear();
}
cout << res.size() << endl;
for(auto it:res){
cout << it.x << " " << it.y << " " << it.pos << endl;
}
}
int main(){
int t=1;
cin >> t;
while(t--){
solve();
}
}