codeforces 1183 A(简单题)B(简单思维)C(思维) D(模拟)E(模拟)G(STL)

A. Nearest Interesting Number(简单题)

题目链接:codeforces 1183A

题意:

    给一个数,输出大于等于这个数并且这个数的每一位的和相加 余 4 == 0

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n, m;
	cin >> m;
	int ans = 0;
	for(int i = 0; i <= 100; i++){
		n = m + i;
		ans = 0;
		while(n){
			ans = ans + n % 10;
			n = n / 10;
		}
		if(ans % 4 == 0){
			cout << m + i << endl;
			break;
		}
	}
	return 0;
} 

B. Equalize Prices(简单思维)

题目链接:codeforces 1183B

题意:

   给n个数,问是否能将这些数改变成同一个数,然后这个数和本身相差 不超过 k,如果能,输出这个数的最大值,否则输出-1

题解:

   如果不能,只有一种情况,最大值和最小值的差 大于 k的2倍

  如果可以,那么答案就是 最小值加上 k

#include<bits/stdc++.h>
using namespace std;
int main(){
	int q;
	cin >> q;
	while(q--){
		int n, k;
		cin >> n >> k;
		int a, mi = 1e8+1, ma = 0;
		for(int i = 1; i <= n; i++){
			cin >> a;
			mi = min(mi, a);
			ma = max(ma, a);
		}
		if((ma - mi) > k * 2){
			cout << -1 << endl;
		}
		else{
			cout << mi + k << endl;
			
		}
		
	}
	return 0;
} 

C. Computer Game(思维)

题目链接:codeforces 1183C

题意:

      电脑初始为 k 格电,有 n 局游戏,每玩第一种游戏消耗 a格电,每玩第二种游戏消耗 b格电,问最多能玩多少次第一种游戏,如果不能玩够 n 局游戏,输出-1(当前电量只有严格大于玩游戏消耗的电量,才能够玩游戏)

题解:

    首先判断是否能够玩 n 局游戏,肯定是 k > min(a, b) * n;

   如果第一种游戏耗电量  <=  第二种,那么就只玩第一种   ans = min(a,  k/a) * n;

  如果第一种游戏耗电量  >   第二种,       ans = min(n, (k-1-n*b) / (a - b) )  [  解释 : (k-1-n*b)的意思为 全部玩 b 剩余的电量,(a-b)为 两种游戏的电量差 ]   

{ 举例解释 :

15(初始电量) 5(5局游戏) 5(玩第一种每次耗电为5) 1(玩第二种游戏每次耗电为1)

首先肯定可以玩够5局,因为 1 * 5  < 15,其次要尽量多玩第一种游戏,那么(k-1-n*b) 就是玩第二种游戏多出来的电,可以将这些电分给 玩第一种游戏,同时扣掉玩1局第二种游戏

}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	int q;
	cin >> q;
	while(q--){
		ll k, n, a, b;
		cin >> k >> n >> a >> b;
		if(k <= min(a, b) * n){
			cout << -1 << endl;
		}
		else{
			if(a <= b){
				cout << min(k/a, n) << endl;
			}
			else{
				cout << min(n, (k-1-n*b) / (a-b)) << endl;
			}
		}
	}
	return 0;
} 

D. Candy Box (easy version)(模拟)

题目链接:codeforces 1183D

题意:

     一个盒子里有 n 块糖,输入n个数,代表a[i] 代表 a[i] 种类的糖数加一,拿出n块糖作为礼物,要求每种类的糖数要不一样,求最多拿出多少块糖。

举例

16

2 1 3 3 4 3 4 4 1 3 2 2 2 4 1 1

有4种糖,每种糖的数量都是4,所以拿出的糖的个数为 4 + 3 + 2 + 1 = 10

题解:

   简单模拟, 坑点,memset(a, 0, sizeof(a)) 的时间复杂度高于 循环

方法一:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+1;
int main(){
	int q;
	cin >> q;
	while(q--){
		int n;
		cin >> n;
		int a[maxn];
                // 刚开始memset(a, 0 ,sizeof(a)) 超时
		for(int i = 1; i <= n; i++){
			a[i] = 0;
		}
		for(int i = 1; i <= n; i++){
			int k;
			cin >> k;
			a[k]++;
		}
		sort(a+1, a+1+n);
		int ans = a[n], i = 1, k = a[n];
		for(int i = n-1; i >= 1; i--){
			if(a[i] >= k){
				ans += min(k-1, a[i]);
				k--;
			}
			else{
				k = a[i];
				ans += a[i];
			}
			if(a[i] == 0 || k <= 1){
				break;
			}
		}
		cout << ans << endl;
	}
	return 0;
} 

  方法二:  使用map和优先队列

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5+100;
     
    struct Node {
       int sum;
       bool operator < (const Node &x) const {
          return this->sum < x.sum;
       }
    };
    int n, t;
    map <int, int> mps;
    priority_queue <Node> qu;
    void init() {
       scanf("%d", &n);
       for(int i = 1; i <= n; i++) {
          int type;
          scanf("%d", &type);
          mps[type]++;
       } 
       map <int, int> :: iterator iter;
       for(iter = mps.begin(); iter != mps.end(); iter++) {
          Node now = {iter->second};
          qu.push(now);
       }
    }
     
    int main() {
       scanf("%d", &t);
       while(t--) {
          init();
          int now = qu.top().sum+1;
          int ans = 0;
          while(!qu.empty()) {
             int sum = qu.top().sum;
             qu.pop();
             if(now == 0 || sum == 0) break;
             if(sum < now) {
                now = sum;
                ans += sum;
             }
    	     else{
                now--;
                ans += now;
             }  	
           }
    	while(!qu.empty()){
            qu.pop();
    	}
       	mps.clear();
       	printf("%d\n", ans);
       }
       return 0;
    }

 

 E. Subsequences (easy version)(模拟)

题目链接:codeforces 1183E

题意:

    给出一个长度为n的字符串,问是否存在k个不同的子序列,然后求子序列的最小花费(每删除一个字符为一个花费)

题解:

   将所有子序列存在set中,判断set的大小是否大于k,先将初始字符串每次从头开始删一个元素,然后存入队列和set中,每次取队列的首元素,重复操作

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+1;
set<string> se;
int main(){
	string s;
	ll n, k, ans = 0;
	cin >> n >> k >> s;
	queue<string> q;
	q.push(s);
	set<string> se;
	se.insert(s);
	while(!q.empty() && se.size() < k){
		string ne = q.front();
		q.pop();
		for(int i = 0; i < ne.size(); i++){
			string v = ne;
			v.erase(i, 1);
			if(!se.count(v) && se.size() < k) {
            q.push(v);
            se.insert(v);
            ans += n - v.size();
         }
		}
	}
	if(se.size() < k){
		cout << -1 << endl;
	}
	else{
		cout << ans << endl;
	}
	return 0;
}

G. Candy Box (hard version) (STL)

题目链接:codeforces 1183G

题意:

     一个盒子里有 n 块糖,输入n个数,代表a[i] 代表 a[i] 种类的糖数加一,并且每个糖果有一个你是否喜欢的标记(0喜欢,1不喜欢),拿出n块糖作为礼物,要求每种类的糖数要不一样,,问糖果最多可以选择多少个,在保证糖果最大的情况下,要求标号为1的糖果最多,输出最大的糖果数和标号为1的糖果数。

题解:

   先按糖数大小排序,如果相同,然后按1的个数排序,如果糖果数相等,优先选1最多的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Node {
    int sum, cnt1;
    bool operator < (const Node &x) const {
        if (this->sum != x.sum)
            return this->sum < x.sum;
        else
            return this->cnt1 < x.cnt1;
    }
};

int n, t;
map <int, int> maps, map1;
priority_queue <Node> qu;
void init() {
   scanf("%d", &n);
   for(int i=1;i<=n;i++) {
      int type, f;
      scanf("%d%d", &type, &f);
      maps[type]++;
      map1[type] += f;
   }
   map <int, int> :: iterator iter;
   for(iter = maps.begin(); iter != maps.end(); iter++) {
      Node now = {iter->second, map1[iter->first]};
      qu.push(now);
   }
}
int main() {
   scanf("%d", &t);
   while(t--){
      init();
		int now = 0;
      int ans = 0, cnt = 0;
      while(!qu.empty()) {
         int sum = qu.top().sum;
         int cnt1 = qu.top().cnt1;
         qu.pop();

         if(sum == 0) break;
         if(sum != now) {
            now = sum;
            ans += sum;
            cnt += cnt1;
         }
	else{
            if(sum == cnt1) {
               sum--;
               cnt1--;
            }
	    else{
               sum--;
            }
            qu.push({sum, cnt1});
         }
      }
      while(!qu.empty()) qu.pop();
      maps.clear();
      map1.clear();
      printf("%d %d\n", ans, cnt);
   }
   return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值