SDUT 2021 Summer Individual Contest - 5
C - Bacteria
大意:n堆细胞,大小分别为a[i]。当且仅当两个细胞堆相同大小,可以合并为一个两倍大小的细胞堆。现可以添加任意大小的任意个细胞堆,如果最终可以合并为一个堆,输出需要添加的细胞堆数,否则输出-1。
思路:(它好像一个二叉树鸭)
- 最终可以合并的条件是:任意一个值都是最小值的2^n(n=0,1,2…)倍。
- 这里要用到小根堆的优先队列,去完成合并成一个值的操作:取出队首的两个值x,y(x <= y)如果两个值相等,完成合并,将2x入队;否则x=x2,直到x == y,每执行一次循环,说明需要添加一堆,则答案自增1。
/*
* @Description:
* @Author: Kirie
* @LastEditTime: 2021-08-09 16:21:42
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <strin
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ll long long
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 7;
priority_queue<ll, vector<ll>, greater<ll> > q; // 小根堆优先队列
bool check(ll num) {
ll now = 1;
while(now <= num) {
//debug(now);
if(num == now) {
return true;
}
now *= 2;
}
return false;
}
ll a[N];
int main()
{
ll n, mn = INF;
cin >> n;
rep(i,1,n) {
cin >> a[i];
mn = min(mn, a[i]);
q.push(a[i]);
}
int flag = 1;
rep(i,1,n) {
if( (a[i] % mn == 0) && check(a[i] / mn) ) {
continue;
} else {
flag = 0;
break;
}
}
ll ans = 0;
if(flag)
while(q.size()) {
//debug(q.top());
ll x = q.top();
q.pop();
ll y = q.top();
q.pop();
while(x != y) {
x *= 2;
ans ++;
}
q.push(x * 2);
}
if(flag)
cout << ans << endl;
else
cout << -1 << endl;
return 0;
}
F - Tickets
大意:对于一个有前导0的6位数,我们称其幸运值为前三位数字之和减去后三位数字之和的绝对值(如123456的幸运值为|1+2+3-4-5-6|=9)。现给出一个数n,求从数字0~n-1中幸运值小于n的数的个数。
思路:该题如果每次读入都求一遍,时间复杂度(O(1e6*2e5))会爆。需要进行一次预处理,之后每次读入输出就很简单了(1e6+2e5)。建议通过函数压缩代码量。
/*
* @Description:
* @Author: Kirie
* @LastEditTime: 2021-08-09 20:06:08
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ll long long
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 7;
int a[N];// * i的幸运值
int b[N]; // * 编号小于i & 幸运值小于a[i] 的和
int st[30]; // * 目前为止幸运值为i的数的个数
int sum(int num ) {
return num / 100 + num / 10 % 10 + num % 10;
}
int cal(int num) {
int a = sum(num / 1000);
int b = sum(num % 1000);
return abs(a - b);
}
void init() {
rep(i,0,N) {
a[i] = cal(i);
st[a[i]] ++;
for(int j = 0; j<a[i]; j++) {
b[i] += st[j];
}
}
}
int main()
{
ios::sync_with_stdio(false);
init();
int n;
cin >> n;
int x;
rep(i,0,n-1) {
cin >> x ;
cout << b[x] << endl;
}
return 0;
}
H - Theater Square
大意:广场大小为n行 * m列,中间(x1,y1)到(x2,y2)的矩形需要空出。现需要铺2 * 1的长砖,要求为横铺,如果摆不下则需要将一块2 * 1的砖拆为1 * 1的小砖补全,问最小要拆多少块。
思路:
-
依据空地位置可以划分为四个区域。
-
对于每个a列b行的区域,如果他的列数a为奇数,则需要b块小砖,否则可以铺满,不需要拆砖。
-
总共需要sum块小砖,则需要sum/2块长砖,如果余下一块需要补全。
/*
* @Description:
* @Author: Kirie
* @LastEditTime: 2021-08-09 14:17:43
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ll long long
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 7;
int cal (int a, int b) { // 一行a个格,一列b个格(列数,行数)
return a % 2 ? b : 0;
}
int main()
{
int n, m;
cin >> n >> m;
int x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
int a = cal(m,x1-1);
int b = cal(m,n-x2);
int c = cal(y1-1,x2-x1+1);
int d = cal(m-y2,x2-x1+1);
int res = a+ b + c + d;
if(res % 2) cout << res / 2 + 1 << endl;
else cout << res / 2 << endl;
return 0;
}
I - Heist
大意:n个数,求其中不连续的缺少的数的个数。
/*
* @Description:
* @Author: Kirie
* @LastEditTime: 2021-08-09 13:08:17
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ll long long
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 7;
int main()
{
int n;
int mx = 0, mn = INF;
int x;
cin >> n;
rep(i,1,n) {
cin >> x;
mx = max(mx,x);
mn = min(mn,x);
}
cout << mx - mn - n + 1 << endl;
return 0;
}
J - Buying a TV Set
大意:求符合下列条件的尺寸的个数:长宽分别不超过a,b,长宽比例为x/y。
思路:让x和y分别除以它们的最大公倍数,再让长和宽的上限分别整除x和y,其中的最小值即符合条件的个数。
/*
* @Description:
* @Author: Kirie
* @LastEditTime: 2021-08-09 13:18:36
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ll long long
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 7;
ll gcd(ll a,ll b) {
if(a % b == 0) return b;
else return gcd(b, a % b);
}
int main()
{
ll a, b, x, y;
cin >> a >> b >> x >> y;
ll g = gcd(x, y);
x /= g;
y /= g;
a /= x;
b /= y;
cout << min(a,b) << endl;
return 0;
}
K - Medians and Partition
大意:对于一串数,对其划分数组,确保每个数组的中位数都大于等于m,问最大能划分多少。
/*
* @Description:
* @Author: Kirie
* @LastEditTime: 2021-08-09 16:28:17
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <iomanip>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define bug cout << "BUG HERE\n"
#define debug(x) cout << #x << " = " << x << endl
#define ll long long
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 7;
int main()
{
int n, m, x;
cin >> n >> m;
int ans = 0, res = 0;
for(int i=0;i<n;i++) {
cin >> x;
if(x < m) ans ++;
else res ++;
}
cout << max(0, res - ans) << endl;
return 0;
}
/*
*
? _oo0oo_
! o8888888o
? 88" . "88
! (| = = |)
? 0\ √ /0
! ___/`---'\___
? .' \\| |// '.
! / \\||| : |||// \
? / _||||| -:- |||||- \
! | | \\\ - /// | |
? | \_| ''\---/'' |_/ |
! \ .-\__ '-' ___/-. /
? ___'. .' /--.--\ `. .'___
! ."" '< `.___\_<★>_/___.' >' "".
? | | : `- \`.;`\ _ /`;.`/ - ` : | |
! \ \ `_. \_ __\ /__ _/ .-` / /
? =====`-.____`.___ \_____/___.-`___.-'=====
! `=---='
?
*
//
*
todo 佛祖保佑 = 永不宕机 && 永无BUG && 永葆发量 = true
*/