您的位置:首页 > 理论基础 > 计算机网络

2017 ACM-ICPC 亚洲区(沈阳赛区)网络赛 - 02 04 05 08 12

2017-09-10 19:26 776 查看


1004 array array array

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 0 Accepted Submission(s): 0



Problem Description

One day, Kaitou Kiddo had stolen a priceless diamond ring. But detective Conan blocked Kiddo's path to escape from the museum. But Kiddo didn't want to give it back. So, Kiddo asked Conan a question. If Conan could give a right answer, Kiddo would return the
ring to the museum.

Kiddo: "I have an array A and
a number k,
if you can choose exactly k elements
from A and
erase them, then the remaining array is in non-increasing order or non-decreasing order, we say A is
a magic array. Now I want you to tell me whether A is
a magic array. " Conan: "emmmmm..." Now, Conan seems to be in trouble, can you help him?

Input

The first line contains an integer T indicating the total number of test cases. Each test case starts with two integers n and k in
one line, then one line with n integers: A1,A2…An.

1≤T≤20

1≤n≤105

0≤k≤n

1≤Ai≤105

Output

For each test case, please output "A is a magic array." if it is a magic array. Otherwise, output "A is not a magic array." (without quotes).

Sample Input

3
4 1
1 4 3 7
5 2
4 1 3 1 2
6 1
1 4 3 5 4 6


Sample Output

A is a magic array.
A is a magic array.
A is not a magic array.


题意:
给你n个数,和k,问你去掉k个数之后,能不能形成不严格上升(下降)序列。

point:
直接正反求上升序列长l,l和n-k比较。

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn=1e5+3;

int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n,k;scanf("%d %d",&n,&k);
int now[maxn];
int a[maxn];
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(now,0,sizeof now);
int cnt=1;
now[1]=a[1];
for(int i=2; i<=n; i++)
{
if(a[i]>=now[cnt])
{
cnt++;
now[cnt]=a[i];
}
else
{
int k=lower_bound(now,now+cnt,a[i])-now;
now[k]=a[i];
}
}
if(cnt>=n-k)
{
printf("A is a magic array.\n");
continue;
}
cnt=1;
now[1]=a
;
for(int i=n-1; i>=1; i--)
{
if(a[i]>=now[cnt])
{
cnt++;
now[cnt]=a[i];
}
else
{
int k=lower_bound(now,now+cnt,a[i])-now;
now[k]=a[i];
}
}
if(cnt>=n-k)
{
printf("A is a magic array.\n");
continue;
}
printf("A is not a magic array.\n");

}
return 0;
}



1002 cable cable cable

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 0 Accepted Submission(s): 0



Problem Description

Connecting the display screen and signal sources which produce different color signals by cables, then the display screen can show the color of the signal source.Notice that every signal source can only send signals to one display screen each time.

Now you have M display
screens and K different
signal sources(K≤M≤232−1).
Select K display
screens from M display
screens, how many cables are needed at least so that **any** K display
screens you select can show exactly K different
colors.

Input

Multiple cases (no more than 100),
for each test case:

there is one line contains two integers M and K.

Output

Output the minimum number of cables N.

Sample Input

3 2
20 15


Sample Output

4
90
Hint



As the picture is shown, when you select M1 and M2, M1 show the color of K1, and M2 show the color of K2.

When you select M3 and M2, M2 show the color of K1 and M3 show the color of K2.

When you select M1 and M3, M1 show the color of K1.


题意:
看图,从每个k向下连线,让每k个组合m都能显示出k中颜色,即和每个k都连线。求最少的线。

POINT:
先让k1-m1,k2-m2,k3-m3……这样连下去。
然后后面的每个m都要连k条线,他们每个都必须和每个k相连。画一下就知道。
答案就是k+(m-k)*k。LL

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <algorithm>
#define LL long long
using namespace std;
const int maxn=1e5+3;

int main()
{
LL a,b;
while(~scanf("%lld %lld",&a,&b))
{
printf("%lld\n",b+(a-b)*b);
}
return 0;
}



1005 number number number

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 0 Accepted Submission(s): 0



Problem Description

We define a sequence F:

⋅ F0=0,F1=1;

⋅ Fn=Fn−1+Fn−2 (n≥2).

Give you an integer k,
if a positive number n can
be expressed by

n=Fa1+Fa2+...+Fak where 0≤a1≤a2≤⋯≤ak,
this positive number is mjf−good.
Otherwise, this positive number is mjf−bad.

Now, give you an integer k,
you task is to find the minimal positive mjf−bad number.

The answer may be too large. Please print the answer modulo 998244353.

Input

There are about 500 test cases, end up with EOF.

Each test case includes an integer k which
is described above. (1≤k≤109)

Output

For each case, output the minimal mjf−bad number
mod 998244353.

Sample Input

1


Sample Output

4


题意:
给你一个斐波那契数列。给你一个k。在自然数中,有good和bad数,每一个good数都能用k个斐波那契加起来得到。bad数就是得不到的。
求最小的bad数。

POINT:
打表找规律。
1 :4

2 :12

3 :33

4 :88

5 :232

6 :609

7 :1596

8 :4180

发现答案就是第。5+2*(k-1) 个斐波那契数【-1】.
ans=F[5+2*(k-1)]-1。
k比较大,用矩阵快速幂求斐波那契数。

#include<iostream>
#include<string.h>
#include<stdio.h>
#include <map>
#include<math.h>
#define LL long long
using namespace std;
const LL maxn=1e5+3;
const LL mod = 998244353;
struct node
{
LL a[3][3];
};
node chen(node a,node b)
{
node ans;
for(LL i=1;i<=2;i++)
{
for(LL j=1;j<=2;j++)
{
ans.a[i][j]=0;
for(LL k=1;k<=2;k++)
{
(ans.a[i][j]+=a.a[i][k]*b.a[k][j])%=mod;
}
}
}
return ans;
}

node jzqkm(node base,LL mi)
{
node ans;
for(LL i=1;i<=2;i++)
{
for(LL j=1;j<=2;j++)
{
if(i==j) ans.a[i][j]=1;
else ans.a[i][j]=0;
}
}
while(mi)
{
if(mi&1) ans=chen(ans,base);
mi>>=1;
base=chen(base,base);
}
return ans;
}
int main()
{
LL k;
while(~scanf("%lld",&k))
{
node base;
base.a[1][1]=1,base.a[1][2]=1,base.a[2][1]=1,base.a[2][2]=0;
node ans=jzqkm(base,5+2*(k-1)-1);
LL now=ans.a[1][1]*1;
now=(now-1+mod)%mod;
printf("%lld\n",now);

}
return 0;
}



1008 transaction transaction transaction

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)

Total Submission(s): 0 Accepted Submission(s): 0



Problem Description

Kelukin is a businessman. Every day, he travels around cities to do some business. On August 17th, in memory of a great man, citizens will read a book named "the Man Who Changed China". Of course, Kelukin wouldn't miss this chance to make money, but he doesn't
have this book. So he has to choose two city to buy and sell.

As we know, the price of this book was different in each city. It is ai yuan in it city.
Kelukin will take taxi, whose price is 1yuan per
km and this fare cannot be ignored.

There are n−1 roads
connecting n cities.
Kelukin can choose any city to start his travel. He want to know the maximum money he can get.

Input

The first line contains an integer T (1≤T≤10)
, the number of test cases.

For each test case:

first line contains an integer n (2≤n≤100000)
means the number of cities;

second line contains n numbers,
the ith number
means the prices in ith city; (1≤Price≤10000)

then follows n−1 lines,
each contains three numbers x, y and z which
means there exists a road between x and y,
the distance is zkm (1≤z≤1000).

Output

For each test case, output a single number in a line: the maximum money he can get.

Sample Input

1
4
10 40 15 30
1 2 30
1 3 2
3 4 10


Sample Output

8


题意:
你可以选择任意两个城市买书或者卖书(可以同一个,收益=0)。
n-1条边链接n个城市,即一颗树。城市有距离,出发的花费为距离*1.求最大的话费。

POINT:
记忆化搜索,因为是无向边,所以不能计算好一个城市立马reutrn。
要记忆边,每条边分成两个方向。这样搜过一条边的话,那肯定不用搜下去了。
而不是靠点来reutrn。

#include<iostream>
#include<string.h>
#include<stdio.h>
#include <vector>
#include <math.h>
#include <algorithm>
#define LL long long
using namespace std;
const LL maxn=103030+3;
int cost[maxn];
struct edge
{
int v,w;
};
int n;
vector<edge> len;
vector<int>G[maxn];
int vis[maxn];
int flag[maxn*2];
int dfs(int u,int pre)
{
for(int i=0;i<G[u].size();i++)
{
int now=G[u][i];
edge e = len[now];
if(e.v==pre) continue;
if(flag[now]) {
vis[u]=max(vis[u],vis[e.v]+cost[e.v]-cost[u]-e.w);
continue;
}
vis[u]=max(vis[u],dfs(e.v,u)+cost[e.v]-cost[u]-e.w);
flag[now]=1;
}
return vis[u];
}
int sz;
void init()
{
for(int i=1;i<=n;i++) G[i].clear(),vis[i]=0;
memset(flag,0,sizeof flag);
len.clear();
sz=0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init();
for(int i=1;i<=n;i++) scanf("%d",&cost[i]);
for(int i=1;i<n;i++)
{
int u,v,w;scanf("%d %d %d",&u,&v,&w);
edge e;
e.v=v,e.w=w;
len.push_back(e);
G[u].push_back(sz++);
e.v=u;
len.push_back(e);
G[v].push_back(sz++);
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,dfs(i,-1));
}
printf("%d\n",ans);

}

return 0;
}



1012 card card card

Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 0 Accepted Submission(s): 0



Problem Description

As a fan of Doudizhu, WYJ likes collecting playing cards very much.

One day, MJF takes a stack of cards and talks to him: let's play a game and if you win, you can get all these cards. MJF randomly assigns these cards into n heaps,
arranges in a row, and sets a value on each heap, which is called "penalty value".

Before the game starts, WYJ can move the foremost heap to the end any times.

After that, WYJ takes the heap of cards one by one, each time he needs to move all cards of the current heap to his hands and face them up, then he turns over some cards and the number of cards he turned is equal to the penaltyvalue.

If at one moment, the number of cards he holds which are face-up is less than the penaltyvalue,
then the game ends. And WYJ can get all the cards in his hands (both face-up and face-down).

Your task is to help WYJ maximize the number of cards he can get in the end.So he needs to decide how many heaps that he should move to the end before the game starts. Can you help him find the answer?

MJF also guarantees that the sum of all "penalty value" is exactly equal to the number of all cards.

Input

There are about 10 test
cases ending up with EOF.

For each test case:

the first line is an integer n (1≤n≤106),
denoting n heaps
of cards;

next line contains n integers,
the ith integer ai (0≤ai≤1000)
denoting there are ai cards
in ith heap;

then the third line also contains n integers,
the ith integer bi (1≤bi≤1000)
denoting the "penalty value" of ith heap
is bi.

Output

For each test case, print only an integer, denoting the number of piles WYJ needs to move before the game starts. If there are multiple solutions, print the smallest one.

Sample Input

5
4 6 2 8 4
1 5 7 9 2


Sample Output

4
Hint
For the sample input:

+ If WYJ doesn't move the cards pile, when the game starts the state of cards is:
4 6 2 8 4
1 5 7 9 2
WYJ can take the first three piles of cards, and during the process, the number of face-up cards is 4-1+6-5+2-7. Then he can't pay the the "penalty value" of the third pile, the game ends. WYJ will get 12 cards.
+ If WYJ move the first four piles of cards to the end, when the game starts the state of cards is:
4 4 6 2 8
2 1 5 7 9
WYJ can take all the five piles of cards, and during the process, the number of face-up cards is 4-2+4-1+6-5+2-7+8-9. Then he takes all cards, the game ends. WYJ will get 24 cards.

It can be improved that the answer is 4.

**huge input, please use fastIO.**


题意:
你可以对数列进行任意次操作,把最前面的已到最后面。
我们需要让拿的卡片最多,是第一列的数加起来最多。而不是手上拥有的,是历史拥有的。
求操作次数最少的且拿的卡片最多。

POINT:
思想为DP中的最大连续子序列和。记录len,当len==n时,则代表全部取掉了,直接break记录起点。
每次更新答案都记录起点。
赛中没看题目,结果会错意了。赛后立马A掉了,代码量也非常少。遗憾。

#include<iostream>
#include<stdio.h>
#include<string.h>
#define LL long long
using namespace std;
const int maxn = 1e6;
int n,a[maxn*2+10],b[maxn*2+10];

int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i+n]=a[i];
for(int i=1;i<=n;i++) scanf("%d",&b[i]),b[i+n]=b[i];
int ans=0;
int now=0;
int get=0;
int len=0;
int k=-1;
for(int i=1;i<=2*n;i++)
{
get+=a[i];
len++;
now+=a[i]-b[i];
if(ans<get)
{
k=i-len+1;
}
if(len==n)
{
break;
}
if(now<0)
{
now=0;
get=0;
len=0;

}
}
printf("%d\n",k-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐