CodeForces Round #643 A-D 题解,E待补
给你一个初始数字a1和计算次数k,每次计算是将ai加上ai这个数的最大的一位数(我们记做maxn)和最小的一位数(我们记做minn)的乘积,得到ai+1。比如a1=487,那a2=487+8*4=519,a3=519+1*9=528,依次类推。
其中a1规模1e18,k规模1e16.
暴力模拟肯定是不要想了
可以发现如果minn=0的话,那从这位数往后的数都不会发生变化了
事实上让minn=0的话,大概只要几十个数就可以做到了
代码:
#include<bits/stdc++.h> using namespace std; #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) #define mem(x,y) memset(x,y,sizeof(x)) #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define mp make_pair #define pb push_back #define db double #define inf 0x3f3f3f3f bool ispow(ll n){return (n&(n-1))==0;} #define lowbit(x) (x&(-x)) const int mod=1e9+7; int main() { fast; int t; cin>>t; while(t--){ ll a,k; cin>>a>>k; ll ans=a; for(ll i=0;i<k-1;i++){ int minn=10,maxn=0; ll temp=ans; while(temp){ int cur=temp%10; minn=min(minn,cur); maxn=max(maxn,cur); temp/=10; } ans+=minn*maxn; if(minn==0) break; } cout<<ans<<'\n'; } return 0; }
有n个人,第i个人的经验值是ei,经验值为ei的人必须被放到有至少ei个人的小队里面才能行动。
求所能划分的最大组数。
例如 样例2
n=5 e=[2,3,1,2,2],那我们可以让1一组,两个2一组,剩下两个人去不了,总共分了2组。
n规模2e5,ei≤n.
直接记录经验值ei的人的个数,把他们分在一组一定是最优的。
如果经验值ei的人有cnt[ei]个,那么答案总数为cnt[ei] / ei
最后再从小到大扫一遍看看能不能再组一队就好(正好扫到经验值为x的时候出现了x个人,就再组一队)
代码:
#include<bits/stdc++.h> using namespace std; #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) #define mem(x,y) memset(x,y,sizeof(x)) #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define mp make_pair #define pb push_back #define db double #define inf 0x3f3f3f3f bool ispow(ll n){return (n&(n-1))==0;} #define lowbit(x) (x&(-x)) const int mod=1e9+7; int e[200005]; int main() { fast; int t; cin>>t; while(t--){ int n; cin>>n; for(int i=0;i<=n;i++) e[i]=0; for(int i=0;i<n;i++) { int r; cin>>r; e[r]++; } ll ans=0; for(int i=1;i<=n;i++) { int temp=(e[i]/i); ans+=temp; e[i]-=(temp*i); } ll sum=0; for(int i=2;i<=n;i++){ sum+=e[i]; if(sum>=i){ sum-=i; ans++; } } cout<<ans<<'\n'; } return 0; }
D比C简单的多,我们先讲D
你需要构造一个长度为N的正整数数组,这些数的和为S。
你还需要再确定一个不大于S的正整数K。
如果可以确定出一个K,让这个数组所有的子数组,他们各自的和都不等于K或S-K,就输出这个数组和你选定的K。
否则输出NO。
这个题我直接猜结论了。
显然当S ≥ 2N的时候,我们只要选K=1,然后数组为[2,2,2....,S-2(N-1)]即可
当S<2N的时候是构造不出来的(H)。下面来证明一下(翻译一下CF的题解):
假设H条件不成立。
让这个数组首尾相连,实际上我们只要找到一个和为K的子数组就可以了(因为首尾相连,找到了K那另一半就是S-K,也满足题意)
对这个数组计算一下前缀和,设计算一遍之后某个数的前缀和为M,然后把前缀和为M+TS(T是任意非负整数,S是数组和)的数给打上标记。
显然,对于我们设的K,M和M+K是不可能同时被标记的
考虑区间[0,2KS),这里面总共有2KN个数被标记了。
把2KS个数按照这样的方式来分:
(0,K), (1,K+1) , ... , (2KS−K−1,2KS−1) 这里面每一对只能有最多1个数被标记
那么就有2KN ≤ KS
我们得到2N ≤ S 这和S<2N矛盾了,所以假设不成立,构造不出来。大概就是这样。
代码:
#include<bits/stdc++.h> using namespace std; #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) #define mem(x,y) memset(x,y,sizeof(x)) #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define mp make_pair #define pb push_back #define db double #define inf 0x3f3f3f3f bool ispow(ll n){return (n&(n-1))==0;} #define lowbit(x) (x&(-x)) const int mod=1e9+7; int main() { fast; int n,s; cin>>n>>s; if(s<2*n) cout<<"NO\n"; else { cout<<"YES\n"; for(int i=0;i<n-1;i++) cout<<2<<' '; cout<<s-2*(n-1)<<'\n'; cout<<1; } return 0; }
给你四个数A,B,C,D,让你找三个数x,y,z使得:
(1)x,y,z三边构成三角形
(2)A ≤ x ≤ B ≤ y ≤ C ≤ z ≤ D
求满足条件的(x,y,z)有多少组。
直接看代码吧,这个题本身没思路,看了qls的讲解就豁然开朗了。
qlstxdy!
#include<bits/stdc++.h> using namespace std; #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0) #define mem(x,y) memset(x,y,sizeof(x)) #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define mp make_pair #define pb push_back #define db double #define inf 0x3f3f3f3f bool ispow(ll n){return (n&(n-1))==0;} #define lowbit(x) (x&(-x)) const int mod=1e9+7; int main() { fast; ll a,b,c,d; cin>>a>>b>>c>>d; ll ans=0; for(ll i=max(a+b,c+1);i<=b+c;i++){//enumerate x+y ll l=max(a,i-c),r=min(b,i-b);//number of methods for fixing x(as well as y) if(l<=r) ans+=(r-l+1)*(min(i-1,d)-c+1);//number of methods for fixing z. } cout<<ans<<'\n'; return 0; } //qlstxdy
大概解释一下,因为要构成三角形,那就一定要满足x + y > z
那我们就去枚举x + y的值,x + y的最小值是a + b。
但是要考虑到一个问题,z的最小值是c,所以要保证它们能构成三角形,我们要从max (a + b, c + 1)开始枚举 x + y
枚举的终点自然就是b + c了
然后我们再去枚举x,注意到一点,你枚举x的同时,y值也是被固定下来了,我们只需要看有多少种z可以取到了。
x的区间起点是max (a , i - c),这里的i = x + y,其实就是保证你枚举出来的a可以构成三角形。
区间终点是 min (b, i - b),如果i - b = x + y - b > b的话,就会让y取不到值。
相对应的,要取z的值,只要保证 z ≤ i - 1即可,可能的种数就是 min (i - 1 , d) - c + 1 种
相乘起来就好,qlstxdy。
E待补,之后有时间会补上的。

浙公网安备 33010602011771号