比赛网址:https://atcoder.jp/contests/nikkei2019-qual
We conducted a survey on newspaper subscriptions. More specifically, we asked each of the NN respondents the following two questions:
As the result, AA respondents answered “yes” to Question 11, and BB respondents answered “yes” to Question 22.
What are the maximum possible number and the minimum possible number of respondents subscribing to both newspapers X and Y?
Write a program to answer this question.
Input is given from Standard Input in the following format:
NN AA BB
Print the maximum possible number and the minimum possible number of respondents subscribing to both newspapers, in this order, with a space in between.
Copy
10 3 5
Copy
3 0
In this sample, out of the 1010 respondents, 33 answered they are subscribing to Newspaper X, and 55 answered they are subscribing to Newspaper Y.
Here, the number of respondents subscribing to both newspapers is at most 33 and at least 00.
10 7 5
5 2
100 100 100
100 100
#include
#include
using namespace std;
int main()
{
int n,a,b;
scanf("%d%d%d",&n,&a,&b);
printf("%d %d\n",min(a,b),max(a+b-n,0));
}
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 200200 points
You are given three strings A,BA,B and CC. Each of these is a string of length NN consisting of lowercase English letters.
Our objective is to make all these three strings equal. For that, you can repeatedly perform the following operation:
What is the minimum number of operations required to achieve the objective?
Input is given from Standard Input in the following format:
NN
AA
BB
CC
Print the minimum number of operations required.
Copy
4
west
east
wait
Copy
3
In this sample, initially A=A= west
、B=B= east
、C=C= wait
. We can achieve the objective in the minimum number of operations by performing three operations as follows:
a
. AA is now wast
.w
. BB is now wast
.s
. CC is now wast
.Copy
9
different
different
different
Copy
0
If A,BA,B and CC are already equal in the beginning, the number of operations required is 00.
Copy
7
zenkoku
touitsu
program
Copy
13
#include
#include
#include
using namespace std;
char a[3][105];
bool s[26];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<=2;i++) scanf("%s",a[i]);
int ans=0;
for(int i=0;i<n;i++)
{
ans+=2;
memset(s,0,sizeof(s));
for(int j=0;j<3;j++)
{
if(s[a[j][i]-'a']) ans--;
s[a[j][i]-'a']=1;
}
}
printf("%d\n",ans);
}
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 400400 points
There are NN dishes of cuisine placed in front of Takahashi and Aoki. For convenience, we call these dishes Dish 11, Dish 22, …, Dish NN.
When Takahashi eats Dish ii, he earns AiAi points of happiness; when Aoki eats Dish ii, she earns BiBi points of happiness.
Starting from Takahashi, they alternately choose one dish and eat it, until there is no more dish to eat. Here, both of them choose dishes so that the following value is maximized: “the sum of the happiness he/she will earn in the end” minus “the sum of the happiness the other person will earn in the end”.
Find the value: “the sum of the happiness Takahashi earns in the end” minus “the sum of the happiness Aoki earns in the end”.
Input is given from Standard Input in the following format:
NN
A1A1 B1B1
::
ANAN BNBN
Print the value: “the sum of the happiness Takahashi earns in the end” minus “the sum of the happiness Aoki earns in the end”.
##Sample Input 1
3
10 10
20 20
30 30
20
In this sample, both of them earns 1010 points of happiness by eating Dish 11, 2020 points by eating Dish 22, and 3030 points by eating Dish 33.
In this case, since Takahashi and Aoki have the same “taste”, each time they will choose the dish with which they can earn the greatest happiness. Thus, first Takahashi will choose Dish 33, then Aoki will choose Dish 22, and finally Takahashi will choose Dish 11, so the answer is (30+10)−20=20(30+10)−20=20.
3
20 10
20 20
20 30
20
In this sample, Takahashi earns 2020 points of happiness by eating any one of the dishes 1,21,2 and 33, but Aoki earns 1010 points of happiness by eating Dish 11, 2020points by eating Dish 22, and 3030 points by eating Dish 33.
In this case, since only Aoki has likes and dislikes, each time they will choose the dish with which Aoki can earn the greatest happiness. Thus, first Takahashi will choose Dish 33, then Aoki will choose Dish 22, and finally Takahashi will choose Dish 11, so the answer is (20+20)−20=20(20+20)−20=20.
6
1 1000000000
1 1000000000
1 1000000000
1 1000000000
1 1000000000
1 1000000000
-2999999997
#include
#include
#include
#define int long long
using namespace std;
const int size=1e5+5;
int a[size],b[size];
int c[size];
bool cmp(int a,int b)
{
return a>b;
}
int32_t main()
{
int n;
scanf("%lld",&n);
long long sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&a[i],&b[i]);
sum=sum+(long long)b[i];
c[i]=a[i]+b[i];
}
sort(c+1,c+1+n,cmp);
long long ans=0;
for(int i=1;i<=n;i+=2) ans+=(long long)c[i];
cout<<ans-sum<<endl;
}
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 500500 points
There is a rooted tree (see Notes) with NN vertices numbered 11 to NN. Each of the vertices, except the root, has a directed edge coming from its parent. Note that the root may not be Vertex 11.
Takahashi has added MM new directed edges to this graph. Each of these MM edges, u→vu→v, extends from some vertex uu to its descendant vv.
You are given the directed graph with NN vertices and N−1+MN−1+M edges after Takahashi added edges. More specifically, you are given N−1+MN−1+M pairs of integers, (A1,B1),…,(AN−1+M,BN−1+M)(A1,B1),…,(AN−1+M,BN−1+M), which represent that the ii-th edge extends from Vertex AiAi to Vertex BiBi.
Restore the original rooted tree.
For “tree” and other related terms in graph theory, see the article in Wikipedia, for example.
Input is given from Standard Input in the following format:
NN MM
A1A1 B1B1
::
AN−1+MAN−1+M BN−1+MBN−1+M
Print NN lines. In the ii-th line, print 0
if Vertex ii is the root of the original tree, and otherwise print the integer representing the parent of Vertex ii in the original tree.
Note that it can be shown that the original tree is uniquely determined.
3 1
1 2
1 3
2 3
0
1
2
The graph in this input is shown below:
It can be seen that this graph is obtained by adding the edge 1→31→3 to the rooted tree 1→2→31→2→3.
6 3
2 1
2 3
4 1
4 2
6 1
2 6
4 6
6 5
6
4
2
0
6
2
对点进行拓扑排序即可
#include
#include
#include
#include
using namespace std;
const int size=1e5+5;
int fa[size],A[size],B[size];
vector<int> G[size];
queue<int> q;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n-1+m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
A[u]++,B[v]++;
}
for(int i=1;i<=n;i++) if(!B[i]) {q.push(i);fa[i]=0;}
while(!q.empty())
{
int u=q.front();
q.pop();
for(auto v:G[u])
{
if(B[v]==1){q.push(v),fa[v]=u;}
B[v]--;
}
}
for(int i=1;i<=n;i++)
{
cout<<fa[i]<<endl;
}
}
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 800800 points
There is a connected undirected graph with NN vertices and MM edges. The vertices are numbered 11 to NN, and the edges are numbered 11 to MM. Also, each of these vertices and edges has a specified weight. Vertex ii has a weight of XiXi; Edge ii has a weight of YiYi and connects Vertex AiAi and BiBi.
We would like to remove zero or more edges so that the following condition is satisfied:
Find the minimum number of edges that need to be removed.
Input is given from Standard Input in the following format:
NN MM
X1X1 X2X2 ...... XNXN
A1A1 B1B1 Y1Y1
A2A2 B2B2 Y2Y2
::
AMAM BMBM YMYM
Find the minimum number of edges that need to be removed.
4 4
2 3 5 7
1 2 7
1 3 9
2 3 12
3 4 18
2
Assume that we removed Edge 33 and 44. In this case, the connected component containing Edge 11 contains Vertex 1,21,2 and 33, and the sum of the weights of these vertices is 2+3+5=102+3+5=10. The weight of Edge 11 is 77, so the condition is satisfied for Edge 11. Similarly, it can be seen that the condition is also satisfied for Edge 22. Thus, a graph satisfying the condition can be obtained by removing two edges.
The condition cannot be satisfied by removing one or less edges, so the answer is 22.
6 10
4 4 1 1 1 7
3 5 19
2 5 20
4 5 8
1 6 16
2 3 9
3 6 16
3 4 1
2 6 20
2 4 19
1 2 9
4
10 9
81 16 73 7 2 61 86 38 90 28
6 8 725
3 10 12
1 4 558
4 9 615
5 6 942
8 9 918
2 7 720
4 7 292
7 10 414
8
对边从小到大排序,枚举每一条边,用并查集枚举每一个联通块,每连接一对联通块,则将一个联通块的点的权值和加到另一个权.对每一个连通块维护其中点的数量,当出现一条新边其边权大于当前联通块点权之和,则将当前连通块中所有的边加入答案.
#include
#include
#include
#include
#define int long long
using namespace std;
struct Edge{
int u,v,w;
Edge(){}
Edge(int u,int v,int w):u(u),v(v),w(w){}
friend bool operator<(Edge a,Edge b)
{
return a.w<b.w;
}
};
const int size=1e5+5;
Edge edges[size];
int val[size];
int sum[size];
int cnt[size];
int fa[size];
int find(int x)
{
if(x==fa[x]) return x;
int f=find(fa[x]);
sum[f]+=sum[x];
sum[x]=0;
cnt[f]+=cnt[x];
cnt[x]=0;
return fa[x]=f;
}
void merge(int fx,int fy)
{
if(fx==fy)
cnt[fy]++;
else
{
sum[fy]+=sum[fx];
sum[fx]=0;
cnt[fy]=cnt[fy]+cnt[fx]+1;
cnt[fx]=0;
fa[fx]=fy;
}
}
int32_t main()
{
int n,m;
int ans=0;
memset(cnt,0,sizeof(cnt));
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&val[i]),fa[i]=i,sum[i]=val[i];
for(int i=1;i<=m;i++) scanf("%lld%lld%lld",&edges[i].u,&edges[i].v,&edges[i].w);
sort(edges+1,edges+1+m);
for(int i=1;i<=m;i++)
{
int x=find(edges[i].u),y=find(edges[i].v);
merge(x,y);
if(edges[i].w<=sum[y])
{
ans+=cnt[y];
cnt[y]=0;
}
}
printf("%lld\n",m-ans);
}