A. Rounding
给你一个非负整数,需要你输出将其舍入到最接近的整数,且末尾是
0
0
0。
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n;
void solve(){
int temp = n % 10;
if(temp >= 5){
n = n / 10 * 10 + 10;
}
else{
n = n / 10 * 10;
}
cout << n << endl;
}
int main(){
cin >> n;
solve();
return 0;
}
B. Proper Nutrition
-
题意 给你
n
,
a
,
b
n,a,b
n,a,b三个整数,找出是否存在
x
,
y
x,y
x,y使得
a
x
+
b
y
=
n
ax+by=n
ax+by=n。 -
解题思路 直接暴力即可,枚举
x
x
x即可确定
y
y
y,而
n
n
n为
1
e
7
1e7
1e7,
O
(
n
)
O(n)
O(n)复杂度可以通过。 -
AC代码
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,a,b;
void solve(){
int maxx = n / b;
for(int i = 0; i <= maxx; ++ i){
int temp = n - i * b;
if(temp % a == 0){
cout << "YES" << endl;
cout << temp / a << " " << i << endl;
return;
}
}
cout << "NO" << endl;
}
int main(){
cin >> n >> a >> b;
solve();
return 0;
}
C. Phone Numbers
-
题意 给你每个人的电话号码信息,需要你对每一个人的电话号码信息进行处理,即若甲的电话号码
x
x
x是甲的电话号码
y
y
y的后缀,那么就删除
x
x
x。按格式输出处理后的信息。 -
解题思路 好题。考察细节,对字符串的处理以及一些必要的数据存储技能。我们首先需要存储每个人的姓名以及电话信息,这里我们采用
v
e
c
t
o
r
vector
vector存储,同时我们需要确定每个人的编号方便索引存储位置以及需要通过编号来确定姓名,这里采用了两个
m
a
p
map
map实现。当然,我们也可以只用一个结构体来实现存储。注意一定要判断每个人是否之前已经存储过了,若存储过直接在原地方存储即可。 处理好之后,我们来分析怎么删除,如果
x
x
x是
y
y
y的后缀,那么第一点就是
l
e
n
(
a
)
≤
l
e
n
(
b
)
len(a) \leq len(b)
len(a)≤len(b)。所以我们可以先对每个人的电话号码按长度大小排序,这样能保证长度要求。那么之后就是要比较是否相等了,根据
x
,
y
x,y
x,y自然能索引到
x
x
x在
y
y
y中的起始判断位置,即使
l
e
n
(
y
)
?
l
e
n
(
x
)
len(y) - len(x)
len(y)?len(x),故只需判断
y
.
s
u
b
s
t
r
(
l
e
n
(
y
)
?
l
e
n
(
x
)
)
=
x
y.substr(len(y) - len(x))=x
y.substr(len(y)?len(x))=x即可。 -
AC代码
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 22 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,cnt;
map<int,string> p1;
map<string,int> p2;
vector<string> ans[N];
string s,num;
bool cmp(string a,string b){
return a.size() < b.size();
}
void solve(){
cout << p2.size() << endl;
for(int i = 1; i <= cnt; ++ i){
sort(ans[i].begin(),ans[i].end(),cmp);
for(int j = 0; j < ans[i].size(); ++ j){
string num1 = ans[i][j];
for(int k = j + 1; k < ans[i].size(); ++ k){
string num2 = ans[i][k];
if(num2.substr(num2.size() - num1.size()) == num1){
ans[i].erase(ans[i].begin() + j);
j --;
break;
}
}
}
cout << p1[i] << " " << ans[i].size() << " ";
for(int j = 0; j < ans[i].size(); ++ j){
cout << ans[i][j] << " ";
}
cout << endl;
}
}
int main(){
cin >> n;
for(int i = 1; i <= n; ++ i){
cin >> s;
if(!p2[s]){
p2[s] = ++ cnt;
p1[cnt] = s;
}
int id = p2[s],tot;
cin >> tot;
while(tot -- ){
cin >> num;
ans[id].push_back(num);
}
}
solve();
return 0;
}
D. Alarm Clock
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e6 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,m,k,x;
int a[N],maxx;
ll cnt;
void solve(){
ll ans = 0;
for(int i = i; i <= maxx; ++ i){
if(i < m)cnt += a[i];
else cnt += (a[i] - a[i - m]);
if(cnt >= k){
ans += cnt - k + 1;
a[i] -= (cnt - k + 1);
cnt = k - 1;
}
}
printf("%lld\n", ans);
}
int main(){
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; ++ i){
scanf("%d", &x);
maxx = max(maxx,x);
a[x] ++;
}
solve();
return 0;
}
E. Squares and not squares
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 2e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n;
ll x;
ll a[N],b[N];
int cnta,cntb;
ll cal(ll *a,int x,int n){
ll res = 0;
sort(a + 1,a + 1 + n);
for(int i = 1; i <= x; ++ i){
res += a[i];
}
return res;
}
void solve(){
if(cnta == cntb){
puts("0");
}
else{
printf("%lld\n",cnta > cntb ? cal(a,cnta - n / 2,cnta) : cal(b,cntb - n / 2,cntb));
}
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
scanf("%lld", &x);
int temp = sqrt(x);
if(temp * temp == x){
if(x)a[++cnta] = 1;
else a[++cnta] = 2;
}
else{
b[++cntb] = min((temp + 1) * (temp + 1) - x,x - temp * temp);
}
}
solve();
return 0;
}
F. Restoring the Expression
-
题意 给定一个数值字符串
s
s
s,需要你分割成
a
,
b
,
c
a,b,c
a,b,c使得
a
,
b
,
c
a,b,c
a,b,c不包含前导零,且
a
+
b
=
c
a+b=c
a+b=c。
n
≤
1
0
6
n\leq 10^6
n≤106 -
解题思路 注意到
n
n
n?的范围,所以我们需要在
O
(
n
)
O(n)
O(n)?时间内解决。我们发现,只需要枚举 = 号的位置,而根据其合理性
m
a
x
(
l
e
n
A
,
l
e
n
B
)
≤
l
e
n
C
≤
m
a
x
(
l
e
n
A
,
l
e
n
B
)
+
1
max(lenA,lenB) \leq lenC \leq max(lenA,lenB) + 1
max(lenA,lenB)≤lenC≤max(lenA,lenB)+1??,那么确定了
l
e
n
C
lenC
lenC?,则有4种可能。
l
e
n
A
=
l
e
n
C
,
l
e
n
B
=
n
?
(
l
e
n
A
+
l
e
n
C
)
,
同
理
l
e
n
B
=
l
e
n
C
,
l
e
n
A
=
n
?
.
.
.
,
l
e
n
A
=
l
e
n
C
?
1
,
l
e
n
B
=
n
?
(
l
e
n
A
+
l
e
n
C
)
,
同
理
l
e
n
B
=
n
?
.
.
.
.
lenA = lenC,lenB = n - (lenA + lenC),同理lenB = lenC,lenA = n -...,lenA = lenC - 1,lenB = n - (lenA + lenC),同理lenB = n - ....
lenA=lenC,lenB=n?(lenA+lenC),同理lenB=lenC,lenA=n?...,lenA=lenC?1,lenB=n?(lenA+lenC),同理lenB=n?....? 所以实际上我们是可以在线性时间内完成字符串的分割的,关键在于判断
a
+
b
=
c
a+b=c
a+b=c????,大数首先排除
O
(
n
2
)
O(n^2)
O(n2)????,那么有什么方法呢?这里引入
h
a
s
h
?
C
o
d
e
hash\ Code
hash?Code?????,也叫散列值,就是将字符串映射成一个数值,一个数值代表一个字符串。字符串hash,【算法学习】字符串哈希(Hash),大家可以看一下一些
b
l
o
g
blog
blog????学习。于是如果我们比较字符串相等,那么可以直接比较它们的
h
a
s
h
?
C
o
d
e
hash\ Code
hash?Code??,这样就达到了
O
(
1
)
O(1)
O(1)???的字符串相等判断,即用空间换时间。字符串
h
a
s
h
hash
hash??需要我们确定
b
a
s
e
base
base??和
m
o
d
mod
mod??,然后对应的
h
a
s
h
hash
hash??公式即为
h
a
s
h
[
i
]
=
(
h
a
s
h
[
i
?
1
]
×
b
a
s
e
+
s
[
i
]
?
′
0
′
)
%
m
o
d
hash[i] = (hash[i - 1] \times base + s[i] - '0') \% mod
hash[i]=(hash[i?1]×base+s[i]?′0′)%mod??,对于此方法,我们需要将
b
a
s
e
base
base??和
m
o
d
mod
mod????取大一点,这样才能避免数值冲突。如果要获取字串的
h
a
s
h
hash
hash??值,那么其对应公式即为
r
e
s
=
(
)
(
h
a
s
h
[
r
]
?
h
a
s
h
[
l
?
1
]
×
b
a
s
e
r
?
l
+
1
)
%
m
o
d
+
m
o
d
)
%
m
o
d
(
由
于
是
减
法
,
所
以
可
能
是
负
值
,
需
要
+
m
o
d
取
余
res = ()(hash[r] - hash[l -1] \times base^{r-l+1})\% mod + mod)\%mod(由于是减法,所以可能是负值,需要+mod取余
res=()(hash[r]?hash[l?1]×baser?l+1)%mod+mod)%mod(由于是减法,所以可能是负值,需要+mod取余?)$???? 那么这里还需提到的一点就是如何得到
a
+
b
a+b
a+b???,就是直接散列值相加即可,因为每个值可以唯一代表一个字符串。
h
a
s
h
hash
hash算法各种各样,能写出适合自己的
h
a
s
h
hash
hash模板即可。 -
AC代码
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e6 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n;
int base = 10;
ll Hash[N],p[N];
string s;
void init(){
n = s.size();
for(int i = 0; i < n; ++ i){
Hash[i + 1] = (Hash[i] * base % P + s[i] - '0') % P;
}
p[0] = 1;
for(int i = 0; i < n; ++ i){
p[i + 1] = p[i] * base % P;
}
}
int get(int l,int r){
if(r < 0 || l - 1 < 0 || r - l + 1 < 0)return 0;
return (Hash[r] - Hash[l - 1] * p[r - l + 1] % P + P) % P;
}
bool check(int lenA,int lenB,int lenC){
if(lenA > lenC || lenB > lenC)return false;
if(lenA < 0 || lenB < 0)return false;
if(s[lenA] == '0' && lenB != 1)return false;
if(s[0] == '0' && lenA != 1)return false;
if((get(1,lenA) + get(lenA + 1,lenA + lenB)) % P != get(lenA + lenB + 1,n)){
return false;
}
return true;
}
void print(int lenA,int lenB,int lenC){
for(int i = 0; i < lenA; ++ i){
putchar(s[i]);
}
putchar('+');
for(int i = lenA; i < lenA + lenB; ++ i){
putchar(s[i]);
}
putchar('=');
for(int i = lenA + lenB; i < n; ++ i){
putchar(s[i]);
}
}
void solve(){
for(int lenC = 1; lenC < n; ++ lenC){
if(s[n - lenC] == '0' && lenC > 1)continue;
if(check(lenC,n - 2 * lenC,lenC)){
print(lenC,n - 2 * lenC,lenC);
break;
}
else if(check(n - 2 * lenC,lenC,lenC)){
print(n - 2 * lenC,lenC,lenC);
break;
}
else if(check(lenC - 1,n - 2 * lenC + 1,lenC)){
print(lenC - 1,n - 2 * lenC + 1,lenC);
break;
}
else if(check(n - 2 * lenC + 1,lenC - 1,lenC)){
print(n - 2 * lenC + 1,lenC - 1,lenC);
break;
}
}
}
int main(){
cin >> s;
init();
solve();
return 0;
}
|