For All :Time Limit: 1s | Memory: 256MB
某单位举办了一次考试,考试有8道题,每道题的得分不一样。选手可以随便做,但最后只统计5道题的得分。现在给出选手每道题的得分,求出他最后的得分最大是多少?
【输入】
8行,每行一个正整数X(0<=X<=150),第i个X表示第i道题的得分。
【输出】
第一行:该选手最后的得分。
第二行:按升序给出的选入计分的5道题的题号。
【样例输入】20
30
50
48
33
66
0
64
【样例输出】
261
3 4 5 6 8
大水题
#include
#include
#include
#include
#include
using namespace std;
struct node
{
int order;
int value;
};
node num[10];
int sto[10];
int cnt=1;
bool cmp(node x,node y)
{
if(x.value
The Croatian version of this contest has the following rules: “Each round of the contest consists of 8
tasks with different point values. Every contestant may solve any of the tasks they choose. However, the
contestant’s final score will be the sum of points earned on any 5 tasks such that this sum is maximized.”
Since the organizers were busy coming up with interesting problems for the contest (and translating
them), they’ve simply forgotten to solve the problem of determining the points scored by each
contestant. Now they are kindly asking you to do it for them.
Write a program that, given the number of points earned by a contestant on each task, determines the
total amount of points scored by that contestant, as well as the sorted list of the 5 problems counting
towards that score. No contestant will ever score the same amount of points on two different
problems.
Mirko学会了开车,但是他还不会在狭窄的街道上掉头。所以,他只能找一个禁止掉头的城镇开车。现在他已经拿到了一个城镇的地图。这个城镇可以看做是R*C的一个表格,每个格子要么为’X’,要么为’.’。’X’表示建筑的一部分,‘.’表示道路。你可以从当前格子往上下左右四个方向移动,当然,‘X’是不能进入的。如果从城镇的任一点出发,你都能找到一条路径回到原点,则认为该城镇没有死胡同,否则该城镇有死胡同,不适合Mirko开车。
【输入】
第一行包含两个整数R和C(3<=R,C<=10),表示城镇地图的行数和列数。
接下来有R行,每行C个字符,要么为’X’,要么为’.’。’X’表示建筑的一部分,‘.’表示道路。
至少有两个格子为‘.’,且保证所有‘.’都是联通的。
【输出】
唯一的一行,如果没有死胡同,输出0,否则输出1.
【样例输入】4 3
XXX
X.X
X.X
XXX
【样例输出】1
大水题,注意特殊情况即可。
#include
#include
#include
#include
#include
#include
using namespace std;
int city[20][20];
int model[20][20];
char data[20];
int X,R;
int step_cnt=-1;
int flag=1;
void reset()
{
for(register int i=1;i<=X;i++)
for(register int j=1;j<=R;j++)
{
model[i][j]=city[i][j];
}
}
void DFS(int x,int y)
{
step_cnt++;
if(step_cnt>1&&(model[x+1][y]==3||model[x-1][y]==3||model[x][y+1]==3||model[x][y-1]==3))
flag=0;
if(model[x][y]!=3)
model[x][y]=0;
if(model[x+1][y]==1)//up
{
DFS(x+1,y);
}
if(model[x-1][y]==1)//down
{
DFS(x-1,y);
}
if(model[x][y-1]==1)//left
{
DFS(x,y-1);
}
if(model[x][y+1]==1)//right
{
DFS(x,y+1);
}
}
int main()
{
scanf("%d%d",&X,&R);
for(register int i=1;i<=X;i++)
{
scanf("%s",data+1);
for(register int j=1;j<=R;j++)
{
city[i][j]=(data[j]=='X' ? 0 : 1);
}
}
for(register int i=1;i<=X;i++)
for(register int j=1;j<=R;j++)
{
if(city[i][j]!=0)
{
reset();
model[i][j]=3;
DFS(i,j);
if(flag==1)
{
printf("1");
return 0;
}
flag=1;
step_cnt=-1;
}
}
printf("0");
return 0;
}
Mirko has been learning to drive, but he still cannot make a U-turn in a narrow street. That’s why he
has decided to go practice in a town where U-turns are forbidden everywhere. This prohibition can be
marked by the following sign:
Mirko has soon figured out that his ideal town must not contain dead-end streets, since it is impossible
to exit such a street without a U-turn (let us assume that Mirko cannot drive in reverse either). Write a
program to analyse a town map and determine whether the town is suitable for Mirko (i.e. whether the
town has any dead-end streets).
The town map is a table with R x C cells, where each cell is a building segment (denoted by X) or a
road surface (denoted by a dot). From a road surface cell, Mirko can move to any of the surrounding
four cells (up, down, left, or right), provided that it is also a road surface (i.e. not a building).
Formally, we will determine that a town is free of dead-end streets if, starting from any road surface cell
and going in any of the possible directions, we can return to the starting cell without making a 180
degrees turn (changing our direction to the opposite one).
Mirko的家庭作业是求两个正整数A,B的最大公约数。因为数字太大,老师提供了N个小点的数,他们的乘积为A,又提供了M个小点的数,他们的乘积为B。
Mirko想验证他的结果,于是他请你写个程序帮帮他。
如果结果超过9位,只需输出最后的9位。
【输入】
输入格式:第一行包含一个正整数N(1<=N<=1000)
第二行包含N个空格隔开的正整数,每个整数小于1000000000,它们的乘积为A。
第三行包含正整数M(1<=M<=1000)
第四行包含M个空格隔开的正整数,每个整数小于1000000000,它们的乘积为B。
【输出】
唯一的一行,表示A和B的最大公约数。如果超过9位,只需要输出最后的9位。
【样例输入1】3
2 3 5
2
4 5
【样例输出1】10
【样例输入2】
3
358572 83391967 82
3
50229961 1091444 8863
【样例输出】
12028
水题,直接因数分解一遍,再查找相同的因数(用哈希),求较小值即可,对于10^9的判定应该很容易的,注意特殊情况;
#include
#include
#define MOD 1000000000
#define ll long long
using namespace std;
bool h[35005];
int p[10005];
int cnt,n,m,l,w;
ll ans=1;
int A[10005];
int B[10005];
ll ksm(ll a,int k)
{
if(k==0)return 1ll;
ll o=ksm(a,k/2);
ll p=o*o;
if(p>=MOD)
{
p%=MOD;
w=1;
}
if(k&1)
{
p*=a;
if(p>=MOD)
{
p%=MOD;
w=1;
}
}
return p;
}
void add(int *K,int a)
{
for(int i=1;i<=cnt;i++)
{
while(a%p[i]==0)
{
a/=p[i];
K[i]++;
}
}
if(a>1)
{
p[++cnt]=a;
K[cnt]++;
a=1;
}
}
int main()
{
//freopen("gcd.in","r",stdin);
//freopen("gcd.out","w",stdout);
for(int i=2;i*i<=MOD;i++)
{
if(!h[i])
p[++cnt]=i;
for(int j=1;j<=cnt&&i*p[j]<=35000;j++)
h[i*p[j]]=1;
}
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int r;
scanf("%d",&r);
add(A,r);
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int r;
scanf("%d",&r);
add(B,r);
}
for(int i=1;i<=cnt;i++)
{
ans*=ksm(p[i],min(A[i],B[i]));
if(ans>=MOD)
{
ans%=MOD;
w=1;
}
}
if(w==1)
printf("%09d",int(ans));
else
printf("%d",int(ans));
}
Mirko has received a homework assignment to compute the greatest common divisor of the two
positive integers A and B. Since the numbers are quite large, the teacher provided him with N smaller
integers whose product is A, and M integers with product B.
Mirko would like to verify his result, so he has asked you to write a program to solve his problem.
If the result is more than 9 digits long, output only the last 9 digits.
在成功的完成了家庭作业后,Mirko无聊地写下了N个数。其中有些数对是他喜欢的,有些数对是他不喜欢的。他喜欢的数对有这样一个特征:两个数中至少有一位共同的数字,不要求他们在同一位。
帮助Mirko计算他喜欢的数对有多少?
【输入】
第一行包含正整数N(1<=N<=1000000)
接下来N行,每行包含1个正整数,在区间[1,1018],表示Mirko写下的数。没有两个数是相等的。
【输出】
唯一的一行,表示Mirko喜欢的数对有多少。
【样例输入1】3
4
20
44
【样例输出1】1
【样例输入2】
4
32
51
123
282
【样例输出2】4
需要用到容斥原理,对于开始的10^6个数,由于本质不同的只有1024个,所以可以压缩成1024种情况,这样总的复杂度就是1024*1024了
#include
using namespace std;
typedef long long LL;
LL num[1<<12];
int n;
LL ans;
inline void Get_int(LL &Ret)
{
char ch;
bool flag=false;
for(;ch=getchar(),ch<'0'||ch>'9';)
if(ch=='-')
flag=true;
for(Ret=ch-'0';ch=getchar(),ch>='0'&&ch<='9';Ret=Ret*10+ch-'0');
flag&&(Ret=-Ret);
}
int main()
{
scanf("%d",&n);
LL tmp=0;
for(int i=1;i<=n;i++) {
tmp=0;
Get_int(tmp);
LL k=0;
while(tmp>0) {
LL t=tmp%10;
tmp/=10;
k|=(1<
After successfully solving his math homework from the previous task, Mirko has become bored, so he
has made a list of N large integers. On the list there are some pairs of numbers that he likes, and some
pairs he doesn’t like.
Mirko has named the pairs that he likes pals. Two numbers are pals if they have at least one digit in
common (not necessarily in the same position).
Help Mirko count how many pairs of numbers in his list are pals.
Mirko写下了下面的函数:
int fun() { int ret = 0; for (int a = X1; a <= Y1; ++a) for (int b = X2; b <= Y2; ++b) ... for (int ret = (ret + 1) % 1000000007; return ret; } |
function fun: longint; var ret: longint; a, b, ... , y, z: longint; begin ret := 0; for a := X1 to Y1 do for b := X2 to Y2 do ... for ret := (ret + 1) mod 1000000007; fun := ret; end; |
计算函数的返回值。
【输入】
第一行包含一个正整数N(1<=N<=26)
接下来N行,第i行包含Xi和Yi,用空格隔开。如果Xi和Yi都为常量,则Xi<=Yi.
【输出】
唯一的一行,包含函数的返回值。
【样例输入1】3
2 3
1 2
1 a
【样例输出1】10
【样例输入2】
3
1 2
a 3
1 b
【样例输出2】11
神犇题!!巨神无比的递推!!这里面涉及到的思想需要慢慢总结
//本代码为COCI官方题解
#include
#include
#include
#include
using namespace std;
const int MAXN = 26;
const int MAXNUM = 100100;
const int MOD = 1000000007;
enum {ROOT, LEFT, RIGHT};
typedef long long llint;
struct node {
int x, y, z;
llint dp[MAXNUM];
vector< node* > children;
node() {}
node(int _x, int _y, int _z) {
x = _x, y = _y, z = _z;
memset(dp, -1, sizeof dp);
}
llint solve(int from = 0) {
llint &ret = dp[from];
if (ret != -1)
return ret;
ret = 0;
if (z == ROOT) {
for (int from = x; from <= y; ++from)
ret = (ret + solve_for(from)) % MOD;
}
if (z == LEFT) {
if (from > y)
return ret;
if (from < y)
ret = solve(from + 1);
ret = (ret + solve_for(from)) % MOD;
}
if (z == RIGHT) {
if (from < x)
return ret;
if (from > x)
ret = solve(from - 1);
ret = (ret + solve_for(from)) % MOD;
}
return ret;
}
inline llint solve_for(int from) {
llint ret = 1;
for (vector< node* >::iterator it = children.begin(); it != children.end(); ++it)
ret = (ret * (*it)->solve(from)) % MOD;
return ret;
}
} nodes[MAXN];
int main(void) {
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
char xi[10], yi[10];
scanf("%s %s", xi, yi);
int x = atoi(xi);
int y = atoi(yi);
int z;
if (x && y)
z = ROOT;
else if (y) {
z = LEFT;
nodes[xi[0] - 'a'].children.push_back(nodes + i);
} else {
z = RIGHT;
nodes[yi[0] - 'a'].children.push_back(nodes + i);
}
nodes[i] = node(x, y, z);
}
llint ans = 1;
for (int i = 0; i < n; ++i)
if (nodes[i].z == ROOT)
ans = (ans * nodes[i].solve()) % MOD;
printf("%lld\n", ans);
return 0;
}
Mirko has written the following function:
C++:
int fun() {
int ret = 0;
for (int a = X1; a <= Y1; ++a)
for (int b = X2; b <= Y2; ++b)
...
for (int
ret = (ret + 1) % 1000000007;
return ret;
}
Pascal:
function fun: longint;
var
ret: longint;
a, b, ... , y, z: longint;
begin
ret := 0;
for a := X1 to Y1 do
for b := X2 to Y2 do
...
for
ret := (ret + 1) mod 1000000007;
fun := ret;
end;
positive integer less than or equal to 100 000 or a name of a variable that some outer loop iterates over.
For example, X3 can be either a, b, or an integer literal. At least one of Xi and Yi will be an integer
literal (i.e. not a variable name) for every i.
Compute the return value of the function.
Mirko的披萨店在镇上很受欢迎,每个人都把披萨作为午餐。Mirko提供外送服务,他的送货速度非常快,所以送货的时间可以忽略不计。镇上每个人都有自己最喜欢的口味,所以,Mirko给每个人做的披萨需要不同的时间。他只有一个小烤炉,每次只能烤一个披萨。如果他给某个人的披萨早于那个人的午餐时间k个时间单位,那么他可以收到k单位的小费,反之,如果晚于客户的午餐时间k个时间单位,那么他将损失k单位的钱。所以,Mirko需要提前安排好每个披萨制作的次序,以保证他的小费尽量多。每个客户的午餐时间是确定的,他的披萨需要花多少时间做好也是确定的。但是,可能客户会有所改变,一旦改变,那么mirko可能需要调整他的计划。Mirko从时刻0开始制作披萨。
【输入】
第一行包含两个正整数N和C,表示镇上的居民数和改变要求的次数。
接下来N行,每行包含两个正整数Li表示居民i的午餐时间,Ti表示居民i的披萨制作好需要的时间。
接下来有C行,每行包含3个正整数:R表示居民的序号,L表示该居民新的午餐时间,T表示该居民的新口味披萨需要制作的时间。
【输出】
第一行输出包含未发生改变时,Mirko能获得的最多的小费。接下来C行,每行表示发生了改变后,Mirko能获得的最多的小费。
【样例数据】
输入样例1: 3 2 10 2 6 5 4 3 1 6 1 3 0 10 |
输入样例2: 4 2 3 2 0 3 4 3 4 1 3 0 4 1 4 5 |
输入样例3: 6 7 17 5 26 4 5 5 12 4 8 1 18 2 3 31 3 4 11 5 4 19 3 5 23 2 6 15 1 5 19 1 3 10 4 |
输出样例1: 3 2 -11 |
输出样例2: -8 -13 -18 |
输出样例3: 27 59 56 69 78 81 82 58 |
【数据规模】
1<=N,C<=200000,
0<=Li,L<=100000
1<=Ti,T<=100000,
1<=R<=N
模型转化后可以发现T是无用的,只需要按照时间递增的顺序执行任务(贪心的经典模型),然后用线段树维护这个递增序的和就行了
//本代码为官方题解
#include
#include
#include
#include
using namespace std;
typedef long long llint;
#define MAX 200005
int N, Q;
int f[ MAX ];
int T[ 2 * MAX ];
int D[ 2 * MAX ];
int I[ 2 * MAX ];
llint SolT, SolD;
vector< pair< int, int > > v;
struct logaritamska {
llint t[ 2 * MAX ];
void update( int x, int v ) {
for( int i = x + 1; i < 2 * MAX; i += i&-i ) t[i] += v;
}
llint query( int x, int y ) {
if( x > y ) return 0;
llint ret = 0;
for( int i = y + 1; i; i -= i&-i ) ret += t[i];
for( int i = x; i; i -= i&-i ) ret -= t[i];
return ret;
}
} p, s;
int pos( int idx ) {
return lower_bound( v.begin(), v.end(), make_pair( -T[idx], idx ) ) - v.begin();
}
void fix( int cpos, int idx, int sgn ) {
SolT += sgn * llint( p.query( 0, cpos - 1 ) + 1 ) * T[idx];
SolT += sgn * s.query( cpos + 1, N + Q - 1 );
SolD += sgn * D[idx];
p.update( cpos, sgn );
s.update( cpos, sgn * T[idx] );
}
int main( void )
{
scanf( "%d%d", &N, &Q );
for( int i = 0; i < N; ++i ) {
scanf( "%d%d", D+i, T+i );
v.push_back( make_pair( -T[i], i ) );
}
for( int i = N; i < N+Q; ++i ) {
scanf( "%d%d%d", I+i, D+i, T+i ); --I[i];
v.push_back( make_pair( -T[i], i ) );
}
sort( v.begin(), v.end() );
for( int i = 0; i < N; ++i ) {
fix( pos( i ), i, +1 );
f[i] = i;
}
printf( "%lld\n", SolD - SolT );
for( int i = N; i < N+Q; ++i ) {
fix( pos( f[I[i]] ), f[I[i]], -1 );
fix( pos( i ), i, +1 );
f[I[i]] = i;
printf( "%lld\n", SolD - SolT );
}
return 0;
}
Mirko’s pizza place is the best one in town. It is so good that all town residents eat pizza for lunch every day. Mirko’s delivery service is so fast that the delivery time is negligible. The problem is baking the pizzas, since all residents have their own favourite topping combination, so baking pizzas for two different residents doesn’t always take the same amount of time. Mirko only has one small baking oven with a capacity of a single pizza at a time, so good scheduling is extremely important and must be
determined before the day starts.
For each of the N town residents (denoted by numbers from 1 to N) we know the baking duration for their favourite pizza (Ti), as well as the moment in the day when they plan on having lunch (Li). If a resident receives their pizza K moments before the planned lunch time, Mirko is rewarded with a tip of K kunas1. On the other hand, if the pizza is delivered K moments late (after the planned lunch time), Mirko must pay the resident K kunas (because of his timely delivery insurance policy). If the pizza is
delivered precisely on time, Mirko won’t get a tip, but he doesn’t have to pay anything either.
Mirko would like to know the maximum total tip (including all insurance payouts as negative tips) that can be earned in a day if pizzas are baked in an optimal order. Notice that Mirko can earn a negative total tip (if he has to pay out more insurance than the amount of tips he receives).
Since residents sometimes change their favourite pizza toppings, as well as their preferred lunch time, Mirko’s schedule must be adapted in order to keep earning optimal tip amounts. Write a program to compute the maximum total tip for the beginning requirements, as well as after each change.
Note: In this town, the day starts at the moment t = 0 and lasts much longer than the time needed to
bake pizzas for all residents. The schedule, including the adaptations, must be determined before the
day starts.
Greatest common divisor of two integers can be defined as the product of their common prime factors, as following:
A = p1^a1 * p2^a2 * … * pn^an
B = p1^b1 * p2^b2 * … * pn^bn
GCD( A, B ) = p1^min(a1,b1) * p2^min(a2,b2) * … * pn^min(an,bn)
where p1..pn are the prime factors and a1..an, b1..bn are corresponding exponents.
We can get the factorization of large numbers A and B by factorizing every of their given factors and summing the prime number exponents over some prime in all factorizations. Next step is computing the GCD using the expression given above. For details check out the attached code.
Alternative solution would be to find GCD of all pairs of numbers Ai, Bj and it to the result (multiply), and divide the numbers A, B with the
same number to prevent adding it to the result several times (in the next iterations).
Required skills: factorization, prime numbers
Category: number theory
First observation we can make is that loops actually represent a system of inequalities:
X1 ≤ a ≤ Y1
X2 ≤ b ≤ Y2
…
XN ≤
Solution to our problems is the number of integer solutions of the given system of inequalities modulo 1000000007.
Lets build a graph with N nodes, each node representing one inequality. From a node which represents inequality of var1 we’ll put an edge towards node of var2 if upper or lower bound of var2 is equal to the same-kind bound of var1.
This graph is disjunct union of directed rooted trees. Since variables in different trees are independent of each other, the number of solutions for inequality system is equal to the product of number of solutions for each of the trees. Let us demonstrate how to calculate the solution for
only one tree.
Let f(root) is equal to the number of solutions of the tree rooted at root. Let g(node, number) equal to the number of solutions of a subtree rooted at node, if variable bound for that node inequality is equal to number. We’ll now make the following claims
for inequality with variable lower bound (it is analog in the case of 2 variable upper bound). This algoritm has complexity of O(NM ), where M is a limit on the upper bound, which is good enough for 70% of the points. Further, we can notice that following holds (for the variable lower bound case - as before it is analog with variable upper bound): points. Further, we can notice that following holds (for the variable lower bound case - as before it is analog with variable upper bound):
Using this observation, complexity becomes O(NM) and this wins 100% points.
Required skills: dynamic programming
Category: dynamic programming, graph theory
Written By SinGuLaRiTy
Time: 2017-03-18