Codeforces Round #422 (Div. 2)
Codeforces Round #422 (Div. 2)
Table of Contents Codeforces Round #422 (Div. 2)Problem A. I'm bored with lifeProblem B.Crossword solvingProblem C. Hacker, pack your bags!
Problem A. I'm bored with life
A. I'm bored with life
Holidays have finished. Thanks to the help of the hacker Leha, Noora managed to enter the university of her dreams which is located in a town Pavlopolis. It's well known that universities provide students with dormitory for the period of university studies. Consequently Noora had to leave Vičkopolis and move to Pavlopolis. Thus Leha was left completely alone in a quiet town Vičkopolis. He almost even fell into a depression from boredom!
Leha came up with a task for himself to relax a little. He chooses two integers A and B and then calculates the greatest common divisor of integers "A factorial" and "B factorial". Formally the hacker wants to find out GCD(A!, B!). It's well known that the factorial of an integer xis a product of all positive integers less than or equal to x. Thus x! = 1·2·3·...·(x - 1)·x. For example 4! = 1·2·3·4 = 24. Recall that GCD(x, y) is the largest positive integer q that divides (without a remainder) both x and y.
Leha has learned how to solve this task very effective. You are able to cope with it not worse, aren't you?
Input
The first and single line contains two integers A and B (1 ≤ A, B ≤ 109, min(A, B) ≤ 12).
Output
Print a single integer denoting the greatest common divisor of integers A! and B!.
Example
input
4 3
output
6
Note
Consider the sample.
4! = 1·2·3·4 = 24. 3! = 1·2·3 = 6. The greatest common divisor of integers 24 and 6 is exactly 6.
题意:求两个数的阶乘的最大公约数
分析:即较小者的阶乘
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
int x = min(a,b);
long long ans = 1;
for(int i=1;i<=x;i++)
ans = ans*(long long)i;
cout<<ans<<endl;
return 0;
}
Problem B.Crossword solving
B. Crossword solving
Erelong Leha was bored by calculating of the greatest common divisor of two factorials. Therefore he decided to solve some crosswords. It's well known that it is a very interesting occupation though it can be very difficult from time to time. In the course of solving one of the crosswords, Leha had to solve a simple task. You are able to do it too, aren't you?
Leha has two strings s and t. The hacker wants to change the string s at such way, that it can be found in t as a substring. All the changes should be the following: Leha chooses one position in the string s and replaces the symbol in this position with the question mark "?". The hacker is sure that the question mark in comparison can play the role of an arbitrary symbol. For example, if he gets string s="ab?b" as a result, it will appear in t="aabrbb" as a substring.
Guaranteed that the length of the string s doesn't exceed the length of the string t. Help the hacker to replace in s as few symbols as possible so that the result of the replacements can be found in t as a substring. The symbol "?" should be considered equal to any other symbol.
Input
The first line contains two integers n and m (1 ≤ n ≤ m ≤ 1000) — the length of the string s and the length of the string t correspondingly.
The second line contains n lowercase English letters — string s.
The third line contains m lowercase English letters — string t.
Output
In the first line print single integer k — the minimal number of symbols that need to be replaced.
In the second line print k distinct integers denoting the positions of symbols in the string s which need to be replaced. Print the positions in any order. If there are several solutions print any of them. The numbering of the positions begins from one.
Examples
input
3 5
abc
xaybz
output
2
2 3
input
4 10
abcd
ebceabazcd
output
1
2
题意:两个字符串s,t,让s,变成t,最少的变几个字母
分析:暴力匹配
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3000+5;
const int inf = 0x3f3f3f3f;
char s[maxn];
char t[maxn];
int main()
{
int a,b;
scanf("%d%d",&a,&b);
scanf("%s%s",s,t);
int ans = inf;
int flag = -1;
for(int i=0;i<=b-a;i++)
{
int tmp = 0;
for(int j=0;j<a;j++) {
if(s[j]!=t[j+i])
tmp++;
}
if(tmp<ans) {
ans = min(ans,tmp);
flag = i;
}
}
printf("%d\n",ans);
for(int i=0;i<a;i++)
if(s[i]!=t[flag+i])
printf("%d ",i+1);
puts("");
return 0;
}
Problem C. Hacker, pack your bags!
C. Hacker, pack your bags!
It's well known that the best way to distract from something is to do one's favourite thing. Job is such a thing for Leha.
So the hacker began to work hard in order to get rid of boredom. It means that Leha began to hack computers all over the world. For such zeal boss gave the hacker a vacation of exactly x days. You know the majority of people prefer to go somewhere for a vacation, so Leha immediately went to the travel agency. There he found out that n vouchers left. i-th voucher is characterized by three integers li, ri, costi — day of departure from Vičkopolis, day of arriving back in Vičkopolis and cost of the voucher correspondingly. The duration of the i-th voucher is a value ri - l**i + 1.
At the same time Leha wants to split his own vocation into two parts. Besides he wants to spend as little money as possible. Formally Leha wants to choose exactly two vouchers i and j (i ≠ j) so that they don't intersect, sum of their durations is exactly x and their total cost is as minimal as possible. Two vouchers i and j don't intersect if only at least one of the following conditions is fulfilled: ri < lj or rj < li.
Help Leha to choose the necessary vouchers!
Input
The first line contains two integers n and x (2 ≤ n, x ≤ 2·105) — the number of vouchers in the travel agency and the duration of Leha's vacation correspondingly.
Each of the next n lines contains three integers li, ri and costi (1 ≤ li ≤ ri ≤ 2·105, 1 ≤ costi ≤ 109) — description of the voucher.
Output
Print a single integer — a minimal amount of money that Leha will spend, or print - 1 if it's impossible to choose two disjoint vouchers with the total duration exactly x.
Examples
input
4 5
1 3 4
1 2 5
5 6 1
1 2 4
output
5
input
3 2
4 6 3
2 4 1
3 5 4
output
-1
Note
In the first sample Leha should choose first and third vouchers. Hereupon the total duration will be equal to (3 - 1 + 1) + (6 - 5 + 1) = 5and the total cost will be 4 + 1 = 5.
In the second sample the duration of each voucher is 3 therefore it's impossible to choose two vouchers with the total duration equal to 2.
题意:有n个时间段旅游,对应有花费,现在挑两个旅游时间段,总时间为x,切费用最少。
分析:数据范围不能暴力枚举,要优化,根据左端点,右端点排序,枚举左端点作为下一个时间段,加入能加入的上一个阶段,这样,这个部分是可以重复利用的,然后找这个部分中与下一个时间段互补的部分,这里采用hash策略。
tip: 排序因子一定要用const修饰
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200000+5;
const int inf = 0x3f3f3f3f;
struct Node {
int l,r,cost;
bool operator<(const Node &o)const{
return r<o.r;
}
}a[maxn],b[maxn];
bool cmp(const Node &x,const Node &y){
return x.l < y.l;
}
map<int,int> mp;
int main()
{
int n,x;
scanf("%d%d",&n,&x);
for(int i=0;i<n;i++) {
scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].cost);
b[i] = a[i];
}
sort(b,b+n,cmp); //左端点
sort(a,a+n);
int i = 0;
long long ans = 1e18;
for(int j=0;j<n;j++) {
while(a[i].r<b[j].l) {
if(a[i].r-a[i].l+1<x) {
if(mp.count(a[i].r-a[i].l+1)) {
mp[a[i].r-a[i].l+1] = min(mp[a[i].r-a[i].l+1],a[i].cost);
}
else mp[a[i].r-a[i].l+1] = a[i].cost;
}
i++;
}
if(mp.count(x-(b[j].r-b[j].l+1)))
ans = min(ans,(long long)mp[x-(b[j].r-b[j].l+1)]+b[j].cost);
}
if(ans==1e18)
puts("-1");
else
printf("%I64d\n",ans);
return 0;
}