CF Codeforces Round #694 (Div. 2)A.Strange Partition(思维)+B.Strange List+C.Strange Birthday Party

A:题意:给n个数,可以进行0~无数次合并,得到的数除以x(向上取整);求最大值和最小值;

解析:一次都不合并最大,全部合并最小;

#include <bits/stdc++.h>
#define  int long long
#define IOS ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const int maxn=2e5+50;
const int INF=0x3f3f3f3f;
using namespace std;
signed main(){
  IOS;
  int t;cin>>t;
  while(t--){
      int n,m;
      cin>>n>>m;
      int sum1=0;
      int cnt=0,sum2=0;
      for(int i=0;i<n;i++){
      int temp;cin>>temp;
      sum1+=temp;
      sum2+=temp/m;
      if(temp%m!=0)cnt++;
       
  }
  if(sum1%m==0)sum1/=m;
  else sum1=sum1/m+1;
  cout<<sum1<<" "<<sum2+cnt<<'\n';
}
   return 0;
}

B题意:给一组数和一个x,从头遍历如果可以整除x就把除得的x个数放进队列后,直到扫到不能整除x的数求这时候的数组之和;

解析:这个题如果纯模拟会爆掉,所以只需要在原数组中求得每一个数最多分多少次就好了,至于怎么求,就是求出数组中每个数最多除以X的次数然后求最小值min,把位置记录下来,这个位置flag以前的可以分min+1次,位置以后的只能分min次;

 1 #include <bits/stdc++.h>
 2 #define  int long long
 3 #define IOS ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
 4 const int maxn=3e5+50;
 5 const int INF=0x3f3f3f3f;
 6 using namespace std;
 7 int ww(int n,int x){//这个函数记录可以除多少次(加上这个数本身就在这个数组里;
 8     int ans=1;
 9    for(int i=x;;i*=x){
10        if(n%i==0)ans++;
11        else break;
12    }
13   return ans;
14 }
15 
16 int a[maxn];
17 signed main(){
18   IOS;
19     int t;
20     cin>>t;
21     while (t--)
22     {    int n,x;
23      
24         cin>>n>>x;
25         int flag=-1;
26         int minn=INF;
27         int flag2=0;
28      //   for(int i=0;i<n;i++)cin>>a[i];
29         for(int i=0; i<n; i++) { 
30             cin>>a[i];
31                 int temp=ww(a[i],x);//cout<<temp<<" ";
32                if(temp<minn){//求最少能分多少次
33                     minn=temp;
34                   flag=i;//记录位置
35                }
36              
37             
38         }
39         int cnt=0;
40     //  cout<<ans<<" ";
41         if(1){
42             for(int i=0;i<n;i++){
43               if(i<flag)cnt+=a[i]*(minn+1);
44               else cnt+=a[i]*minn;
45              // cout<<a[i]*ans<<" ";
46             }
47         }
48        cout<<cnt<<'\n';
49 }
50  return 0;
51 }

C我忘了题目,等今天这场打完了再看一下,

C题意就是,有N个好朋友和M个礼物,其中m个礼物是按价格升序排列的,每个好朋友有一个数k要求花费第k个数这么多钱或者把第k个前的礼物买给他(每种礼物只有一个;

思路:首先把好朋友排个序,把难缠的(k大的放在前面,然后遍历一遍,礼物从价格低到高每次比较是给钱还是买礼物然后把花费加起来O(n)就可以了;

 

 1 #include <bits/stdc++.h>
 2 #define  int long long
 3 #define IOS ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
 4 const int maxn=3e5+50;
 5 const int INF=0x3f3f3f3f;
 6 using namespace std;
 7 int a[maxn],b[maxn];
 8 bool cmp(int a,int b){
 9     return a>b;
10 }
11 signed main(){
12   IOS;
13   int t;cin>>t;
14   while(t--){
15       int n,m;
16       cin>>n>>m;
17       for(int i=1;i<=n;i++)cin>>a[i];//好朋友
18       for(int i=1;i<=m;i++)cin>>b[i];//礼物
19       sort(a+1,a+1+n,cmp);
20       int ans=0;
21       int l=1;
22       for(int i=1;i<=n;i++){
23           int x=b[l],y=b[a[i]];//X表示当前最便宜的礼物数,y表示如果给钱要花多少
24           if(l>m)x=INF;//如果礼物无了,设成最大
25           ans+=min(x,y);//cout<<x<<" "<<y<<" "<<ans<<'\n';
26         l++;
27       }
28       cout<<ans<<'\n';
29   }
30  return 0;
31 }

flag:不再缺席cf

posted @ 2021-01-08 22:22  小靖快去敲代码  阅读(110)  评论(0编辑  收藏  举报