题解报告(CDUT暑期集训——第一场)
A - Maximum Multiple
HDU - 6298
-
思路:先按照题意打表 发现规律 就出来了(最开始没开long long贡献了3发 然后又忘了换行又贡献了一发
-
AC代码
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll Pow(ll a, ll b, ll c){
ll ans = 1;
a %= c;
while (b){
if (b & 1) ans = (ans * a) % c;
a = (a * a) % c;
b >>= 1;
}
return (ans % c);
}
bool cmp(const int &a, const int &b){
return a < b;
}
ll gcd(ll x, ll y){
return x % y == 0 ? y : gcd(y, x % y);
}
ll lcm(ll x, ll y){
return x / gcd(x, y) * y;
}
const int MAXN = 2000 + 5;
const int mod = 1e9 + 7;
ll comb[MAXN][MAXN];
void init(){
for (int i = 0; i < MAXN; i ++ ){
comb[i][0] = comb[i][i] = 1;
for (int j = 1; j < i; j ++ ){
comb[i][j] = comb[i - 1][j] + comb[i - 1][j - 1];
comb[i][j] %= mod;
}
}
}
ll mult_mod(ll a, ll b, ll c){
a %= c;
b %= c;
ll res = 0;
while (b){
if (b & 1){
res += a;
res %= c;
}
a <<= 1;
a %= c;
b >>= 1;
}
return res;
}
int main(){
ll t;
scanf("%lld", &t);
ll n;
while (t--){
scanf("%lld", &n);
if (n % 12 == 1 || n % 12 == 2 || n % 12 == 5 || n % 12 == 7 || n % 12 == 10 || n % 12 == 11) printf("-1
");
else{
if (n % 3) printf("%lld", (n / 4) * (n / 4) * (n / 4) * 2);
else printf("%lld", (n / 3) * (n / 3) * (n / 3));
}
}
return 0;
}
B - Balanced Sequence
HDU - 6299
-
思路:贪心 先把每个串里面的括号匹配之后去掉 再对它们排序 匹配剩下的括号就行了(开始莫名其妙MLE了九发 找不到原因 然后再交TLE RE 后面发现cmp写错了 改了之后就过了
-
AC代码
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<string>
#include<string.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int N = 100010;
int n, t, ans, cnt_l;
char c[N];
struct st{
int l;
int r;
}s[N];
bool cmp(st a, st b){
if (a.l > a.r && b.l <= b.r) return true;
else if (a.l <= a.r && b.l > b.r) return false;
else if (a.l > a.r && b.l > b.r) return a.r < b.r;
else return a.l > b.l;
}
int main(){
scanf("%d", &t);
while (t --){
ans = 0;
cnt_l = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ){
s[i].l = 0;
s[i].r = 0;
scanf("%s", c);
for (int j = 0; j < strlen(c); j ++ ){
if (c[j] == '(') s[i].l ++;
if (c[j] == ')') s[i].l == 0 ? s[i].r ++ : (s[i].l -= 1, ans += 2);
}
}
sort(s + 1, s + n + 1, cmp);
for (int i = 1; i <= n; i ++ ){
if (s[i].r > cnt_l) s[i].r = cnt_l;
ans += 2 * s[i].r;
cnt_l += s[i].l - s[i].r;
}
printf("%d
", ans);
}
return 0;
}
C - Triangle Partition
HDU - 6300
-
思路:贪心 写个struct对x排个序就出来了(
-
AC代码
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll Pow(ll a, ll b, ll c){
ll ans = 1;
a %= c;
while (b){
if (b & 1) ans = (ans * a) % c;
a = (a * a) % c;
b >>= 1;
}
return (ans % c);
}
//bool cmp(const int &a, const int &b){
// return a < b;
//}
ll gcd(ll x, ll y){
return x % y == 0 ? y : gcd(y, x % y);
}
ll lcm(ll x, ll y){
return x / gcd(x, y) * y;
}
const int MAXN = 2000 + 5;
const int mod = 1e9 + 7;
ll comb[MAXN][MAXN];
void init(){
for (int i = 0; i < MAXN; i ++ ){
comb[i][0] = comb[i][i] = 1;
for (int j = 1; j < i; j ++ ){
comb[i][j] = comb[i - 1][j] + comb[i - 1][j - 1];
comb[i][j] %= mod;
}
}
}
ll mult_mod(ll a, ll b, ll c){
a %= c;
b %= c;
ll res = 0;
while (b){
if (b & 1){
res += a;
res %= c;
}
a <<= 1;
a %= c;
b >>= 1;
}
return res;
}
const int N = 1010;
struct point{
int x, y;
int index;
}p[N];
bool cmp(point a, point b){
if (a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int main(){
int t;
scanf("%d", &t);
int n;
while (t--){
scanf("%d", &n);
for (int i = 1; i <= 3 * n; i ++ ){
scanf("%d%d", &p[i].x, &p[i].y);
p[i].index = i;
}
sort(p + 1, p + 3 * n + 1, cmp);
for (int i = 1; i <= n; i ++ )
printf("%d %d %d
", p[(i - 1) * 3 + 1].index, p[(i - 1) * 3 + 2].index, p[(i - 1) * 3 + 3].index);
}
return 0;
}
D - Distinct Values
HDU - 6301
-
__思路:贪心 先排序 后用set维护就行了(学到了一个新东西 迭代器赋值前要加* 要不然会报错 __
-
AC代码
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<set>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll Pow_mod(ll a, ll b, ll c){
ll ans = 1;
a %= c;
while (b){
if (b & 1) ans = (ans * a) % c;
a = (a * a) % c;
b >>= 1;
}
return (ans % c);
}
const int N = 1000010;
int t, n, m, L, R;
set<int> st;
int ans[N];
struct node{
int l, r;
}interval[N];
int cmp(node a, node b){
return a.l == b.l ? a.r < b.r : a.l < b.l;
}
int main(){
scanf("%d", &t);
while (t -- ){
st.clear();
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i ++ )
scanf("%d%d", &interval[i].l, &interval[i].r);
sort(interval + 1, interval + m + 1, cmp);
L = interval[1].l;
R = interval[1].r;
for (int i = 1; i <= n; i ++ ){
st.insert(i);
ans[i] = 1;
}
for (int i = L; i <= R; i ++ ){
ans[i] = *st.begin();
st.erase(st.begin());
}
for (int i = 2; i <= m; i ++ ){
while (L < interval[i].l){
st.insert(ans[L]);
L ++;
}
while (R < interval[i].r){
if (R < interval[i].l - 1) R ++;
else{
R ++;
ans[R] = *st.begin();
st.erase(st.begin());
}
}
}
for (int i = 1; i < n; i ++ ) printf("%d ", ans[i]);
printf("%d
", ans[n]);
}
}
G - Chiaki Sequence Revisited
HDU - 6304
-
思路:先打表 找规律 令f(i)为i出现的次数 再打表 去掉a1 = 1出现的一次 可以得到f(2 * i) = f(i) + 1 f(2 * i + 1) = 1 当时到了这里就卡死了 卡了两个半小时 然后想着把f(i) = n, n = 1, 2, 3, ...打印出来看下 结果一打印就发现了f(i)相同的构成了一个首项为2^(n-1) 公差为2^n的等差数列 就直接根据公式就解出来了 结束前没能写出来 结束之后几分钟写好交了三发才过 第一发用自己写的乘法取膜函数tle了 第二发有一处忘了取膜贡献了一发wa 第三发才终于过了
-
AC代码
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll Pow_mod(ll a, ll b, ll c){
ll ans = 1;
a %= c;
while (b){
if (b & 1) ans = (ans * a) % c;
a = (a * a) % c;
b >>= 1;
}
return (ans % c);
}
ll Pow(ll a, ll b){
ll ans = 1;
while (b){
if (b & 1) ans *= a;
a *= a;
b >>= 1;
}
return ans;
}
bool cmp(const int &a, const int &b){
return a < b;
}
ll gcd(ll x, ll y){
return x % y == 0 ? y : gcd(y, x % y);
}
ll lcm(ll x, ll y){
return x / gcd(x, y) * y;
}
const int MAXN = 2000 + 5;
const int mod = 1e9 + 7;
ll comb[MAXN][MAXN];
void init(){
for (int i = 0; i < MAXN; i ++ ){
comb[i][0] = comb[i][i] = 1;
for (int j = 1; j < i; j ++ ){
comb[i][j] = comb[i - 1][j] + comb[i - 1][j - 1];
comb[i][j] %= mod;
}
}
}
ll mult_mod(ll a, ll b, ll c){
a %= c;
b %= c;
ll res = 0;
while (b){
if (b & 1){
res += a;
res %= c;
}
a <<= 1;
a %= c;
b >>= 1;
}
return res;
}
const int N = 63;
ll s[N], t[N];
ll calc(ll n){
ll tmp = 0;
if (n == 1) return 1;
n -= 1;
for (int i = N - 1; i >= 0; i -- ){
while (s[i] <= n){
n -= s[i];
tmp += t[i];
}
}
return tmp;
}
ll get_pos(ll n){
ll pos = 0;
if (n == 1) return 1;
n -= 1;
for (int i = N - 1; i >= 0; i -- ){
while (t[i] <= n){
n -= t[i];
pos += s[i];
}
}
return pos + 1;
}
int main(){
s[0] = 1;
t[0] = 1;
for (int i = 1; i < N; i++){
s[i] = s[i - 1] * 2 + 1;
t[i] = t[i - 1] * 2;
}
int T;
scanf("%d", &T);
ll n;
while (T--){
scanf("%lld", &n);
ll tmp = calc(n);
ll cnt = n - get_pos(tmp);
ll sum = 0;
for (int i = 1; t[i - 1] <= tmp; i ++ ){
ll b1 = t[i - 1];
ll d = t[i];
ll n_ = (tmp - b1) / d;
if ((tmp - b1) % d) n_ += 1;
ll bn = b1 + (n_ - 1) * d;
ll sum_b = (b1 % mod + bn % mod) * (n_ % mod) * 500000004 % mod;
sum += i * sum_b % mod;
sum %= mod;
if (!((tmp - b1) % d)) sum += (cnt % mod) * (tmp % mod) % mod;
sum %= mod;
}
printf("%lld
", sum + 1);
}
return 0;
}
K - Time Zone
HDU - 6308
-
思路:数学题 把时区差换算成时间差(分钟) 然后换算过去就行了 最开始写了个贼蠢的模拟 写的很长 还wa了 后面才想起来没写%02d才wa的
-
AC代码
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll Pow(ll a, ll b, ll c){
ll ans = 1;
a %= c;
while (b){
if (b & 1) ans = (ans * a) % c;
a = (a * a) % c;
b >>= 1;
}
return (ans % c);
}
bool cmp(const int &a, const int &b){
return a < b;
}
ll gcd(ll x, ll y){
return x % y == 0 ? y : gcd(y, x % y);
}
ll lcm(ll x, ll y){
return x / gcd(x, y) * y;
}
const int MAXN = 2000 + 5;
const int mod = 1e9 + 7;
ll comb[MAXN][MAXN];
void init(){
for (int i = 0; i < MAXN; i ++ ){
comb[i][0] = comb[i][i] = 1;
for (int j = 1; j < i; j ++ ){
comb[i][j] = comb[i - 1][j] + comb[i - 1][j - 1];
comb[i][j] %= mod;
}
}
}
ll mult_mod(ll a, ll b, ll c){
a %= c;
b %= c;
ll res = 0;
while (b){
if (b & 1){
res += a;
res %= c;
}
a <<= 1;
a %= c;
b >>= 1;
}
return res;
}
int main(){
int t;
scanf("%d", &t);
int a, b;
while (t--){
char flag;
double utc;
scanf("%d %d UTC%c%lf", &a, &b, &flag, &utc);
int tmp = (int)(utc * 10 + 0.1);
if (flag == '-') tmp = -tmp;
int sum = a * 60 + b + (tmp * 6 - 8 * 60);
sum %= (24 * 60);
if (sum < 0) sum += (24 * 60);
printf("%02d:%02d
", sum / 60, sum % 60);
}
return 0;
}