文章目录
前言
蒟蒻过来补题,大佬误嘲 (QAQ)D2、E、F题暂时不在能力范围内呀~~以后补上
A. Polycarp and Coins
题目的大致意思:给定一正整数为商品的总价,要求尽量用相等数量的面值为1伯勒和2伯勒的钱去买该商品。(水题无疑了)
题解:
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int sum=n/3;
if(sum*3==n)cout<<sum<<" "<<sum<<endl;
else{
if(n-sum*3==2) cout<<sum<<" "<<sum+1<<endl;
else cout<<sum+1<<" "<<sum<<endl;
}
}
return 0;
}
B1.Wonderful Coloring - 1
题目的大致意思:将给定字符串的每个字符进行涂色,每个字符可以涂也可以不涂,要求两种颜色的字符数量相等,但是同一种字符不能图相同颜色。(还是水题)
题解:
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
string s;
cin>>s;
int a[26]={0};//开始的时候把这个定义在外面了,就是错误答案
int sum=0;
for(int i=0;i<s.size();i++){
a[s[i]-'a']++;
if(a[s[i]-'a']<=2)sum++;
}
cout<<sum/2<<endl;
}
return 0;
}
B2.Wonderful Coloring - 2
题目的大致意思:这题是B1题的升级版,给定k种颜色能够使用,给相同数字涂不同颜色,相同颜色不能有相同颜色,每种颜色的数字个数要相同,最后输出每个数字涂色的编号,多种涂法输出任意一种。(从这一题开始难度提升了)
解题思路: 先将相同的数字进行记数,如果它重复的个数大于已有的颜色数目,就需要用到所有的颜色。剩下没有重复或者有重复但是重复个数不到k的就可以从1到k进行循环涂色,这样就能保证每种颜色最后的数目相同了(不够循环整数次的多的就不涂色)。剩下的就看代码实现啦!绕了好久才理清楚(哭唧唧~)
题解:
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 2e5+10;
int a[N];//用于储存最初的数组并进行排序方便统计重复次数
int b[N];//用于储存除去重复个数大于k的数字后剩下的数字
int c[N]; //用于储存最初的数组,并保持不变
queue<int> q[N];//利用先进先出的优势储存每个数据涂色的编号
int main()
{
int t;
cin>>t;
while(t--){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
c[i] = a[i];//将输入的数据拷贝到数组储存起来,方便后面涂色使用
}
sort(a+1,a+n+1); //排序后方便统计重复次数啦
int j=1;
int cnt=1;
b[1]=a[1];//第一个数据不要漏掉了
for(int i=2;i<=n;i++){
if(a[i]==a[i-1]) cnt++;//统计重复次数
else cnt=1;
if(cnt<=k){
j++;
b[j]=a[i];//将筛掉重复次数大于k次的数据储存起来
}
}
int d = j/k*k; //利用能够整除的次数求能在循环内的数据个数 ,保证所有颜色数量相等
int now=1;//涂色编号
for(int i=1;i<=d;i++){
q[b[i]].push(now);//就算还有数据重复,但是重复个数小于k都会被后一次的涂色所覆盖,不会导致相同颜色有重复的情况
now++;
if(now>k) now=1;
}
//这时候输出的时候c数组就要起作用啦!
for(int i=1;i<=n;i++){
if(q[c[i]].empty()) cout<<"0 ";
else{
cout<<q[c[i]].front()<<" ";
q[c[i]].pop();
}
}
cout<<endl;
}
return 0;
}
C.Interesting Story
题目的大致意思:给定几个字符串,字符串都只由a,b,c,d,e组成,将字符串组装起来,使得其中一个字母的重复次数大于剩余所有字母的数目总和,输出使用字符串的最大个数。
解题思路:将每一个字符串的每一个字母的个数先进行统计,然后再根据题目的运算(字母个数-剩余其它字母总和)并把数据储存起来。最后对每一个字符串的相同字母所求的对应运算差进行排序,之后从高位开始求和并记录所用字符串的个数,当和的值小于或者等于0时就是当前字母能满足题意的临界状态,这时的字符串个数就是该字母满足题意的个数。同理求5个字母分别的最大个数之后取最大值就是最终需要输出的数值。这里似乎需要用到二维数组对每一个字符串的5个字母分别记录,但是二维数组不方便进行每一行或者每一列的排序,就考虑用到vector容器(现在来看代码加深理解吧,借鉴了大佬们的代码)
题解:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>w[5];//储存每个字符串种每个字母的数据差(题中运算)
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
string s;
for (int i = 0; i < n; i++) {
cin >> s;
int abc[5] = { 0 };
for (int j = 0; j < s.size(); j++) {
abc[s[j] - 'a']++;//每个字符串中的每个字母计数
}
for (int j = 0; j < 5; j++) {
w[j].push_back(abc[j] * 2 - s.size());//实质上是abc[j]-(s.size()-abc[j])
}
}
int ans = 0;
for (int i = 0; i < 5; i++) {
sort(w[i].begin(), w[i].end());//每个字母相应数据排序
int sum = 0;
int temp = 0;
for (int j = n - 1; j >= 0; j--) {
sum += w[i][j];
if (sum > 0) temp++;
else break;
}
if (temp > ans) ans = temp;
}
cout << ans<<endl;
for (int i = 0; i < 5; i++) w[i].clear();//一定记得清空容器中的数据,一遍下一个用例使用
}
return 0;
}
D1. Domino (easy version)
题目的大致意思:这题好像家里装修贴地砖一样,有横着的砖块和竖着的砖块,规格都是占两格。现在给n*m(长m宽n)的面积给你,需要你用砖块将它填满并且使用的横着的砖块恰好是k个,可以就输出YES,不可以就输出NO。
解题思路:分情况讨论,当n为奇数,m为偶数时;n为偶数,m为奇数时;n和m同为奇数或者同为偶数时。n为奇数时必定有一行要用到横着的地砖,这时候如果横着的不够用,就一定不行;m为奇数时同理;当n和m同为奇数或偶数时,k为奇数时一定不行
题解:
#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m, kh;
cin >> n >> m >> kh;
int kv = n * m / 2 - kh;
if (n & 1)//假如宽n是奇数(位运算判断奇偶,按照二进制来看)
{
kh -= m / 2;
if (k < 0)
{
cout << "NO\n";
continue;
}
}
else if (m & 1) //假如长m为奇数
{
kv -= n / 2;
if (kv < 0)
{
cout << "NO\n";
continue;
}
}
if ((kh & 1) || (kv & 1))//n和m同为奇数或者偶数
{
cout << "NO\n";
continue;
}
cout << "YES\n";
}
return 0;
}
总结
又是烧脑的一天,头发-1-1-1-1…QAQ