NOI2016 山东省队选拔第一轮 Day 1
被虐得好爽。
T1 储能表
【问题描述】
有一个 n 行m 列的表格,行从
每个格子都储存着能量。最初,第 i 行第
所以,整个表格储存的总能量是,
随着时间的推移,格子中的能量会渐渐减少。
一个时间单位,每个格子中的能量会减少 1。
显然,一个格子的能量减少到
也就是说,k 个时间单位后,整个表格储存的总能量是,
给出一个表格,求
由于总能量可能较大,输出时对 p 取模。
【输入格式】
第一行一个整数
接下来 T 行,每行四个整数
【输出格式】
共 T 行,每行一个数,表示总能量对
【样例输入】
3
2 2 0 100
3 3 0 100
3 3 1 100
【样例输出】
2
12
6
【数据规模和约定】
【想法】
这个题目我开始是想找规律,然后确实发现了一些“规律”,结果敲了半个小时发现错了,改进“规律”后又敲了半个小时,结果发现又错了,然后又改进………
然后,然后就没有然后了。
当我幡然醒悟,考试就结束了QWQ
据说题目正解是 “shuwei” DP,反正我是不懂。
T2 数字配对
【问题描述】
有 n 种数字,第
若两个数字 ai 、aj 满足, ai 是 aj 的倍数,且 aiaj 是一个质数,那么这两个数字可以配对,并获得 ci⋅cj 的价值。
一个数字只能参与一次配对,可以不参与配对。
在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。
【输入格式】
第一行一个整数
第二行 n 个整数
第三行 n 个整数
第四行 n 个整数
【输出格式】
一行一个数,最多进行多少次配对。
【样例输入】
3
2 4 8
2 200 7
-1 -2 1
【样例输出】
4
【数据规模和约定】
【Solution】
在考场上根本就没有想,只是最开始阅读所有题目时扫了一眼,之后就再也没有看过了。
当时就感觉这道题有二分图的味道,配对是吧,那不就是连边吗???
我们将所有满足条件的几对不同种类的数连起来,然后从源点向这对数的一边连一条容量为 bi,费用为 0 的边,从这对数的另一边向汇点连一条容量为
然后不断地找最小费用增广路。
每次增广,我们付出的都是最小的代价。
所以,当 当前最小费用 大于 0 时,我们就可以知道,当前的最大流就为所求解。
注意,最后一次增广时的流量也要计算进去啊(找到能使 当前最小费用 小于等于
问题又来了,那我们怎么判断从一对数的哪一边连到汇点和源点呢??
根据唯一分解定理,
ai=Pd11⋅Pd22⋅Pd33......Pdll,dk∈N,
aj=Pe11⋅Pe22⋅Pe33……Peqq,ek∈N,
所以,若 ai≡0(mod aj) 且 aiaj 为质数,那么有且只有一个 k∈N∗,使得 dk=ek+1,dm=em,m≠k,l=q。
综上,∑k=1pdk=∑k=1qek+1,所以 ai 与 aj 的质因子个数必定一奇一偶,所以我们可以按照质因子个数的奇偶性将一对数对给分成两边。
问题得解。
【Code】
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <queue>
- #include <cmath>
- #define LL long long
- #define ANOTHER 200
- #define Min(x,y) ((x)<(y)?(x):(y))
- #define INF 0x3f3f3f3f
- #define ss 0
- #define tt 500
- using namespace std;
- LL n,Minx,ans,cnt,tot,Max_flow,sum;
- bool flag;
- bool lefts[1000];
- LL a[1000],b[1000],c[1000];
- LL nxt[100100],head[510];
- LL data[100100],wei[100100],flow[100100];
- LL f[300][300];
- LL dis[510],pre[510];
- bool in_stack[510];
- queue<LL>q;
- void add(LL x,LL y,LL a,LL b){
- nxt[cnt]=head[x];data[cnt]=y;wei[cnt]=b;flow[cnt]=a;head[x]=cnt++;
- nxt[cnt]=head[y];data[cnt]=x;wei[cnt]=-b;flow[cnt]=0;head[y]=cnt++;
- }
- bool BFS(){
- memset(dis,0x3f,sizeof dis);dis[ss]=0;in_stack[ss]=true;q.push(ss);pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- LL now=q.front();
- q.pop();
- in_stack[now]=false;
- for(LL i=head[now];i!=-1;i=nxt[i]){
- if(flow[i]!=0&&dis[data[i]]>dis[now]+wei[i]){
- dis[data[i]]=dis[now]+wei[i];
- pre[data[i]]=i^1;
- if(!in_stack[data[i]]){
- in_stack[data[i]]=true;
- q.push(data[i]);
- }
- }
- }
- }
- return pre[tt]!=-1;
- }
- bool dfs(){
- LL Low=INF;
- for(LL i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow[i^1]);
- for(LL i=pre[tt];i!=-1;i=pre[data[i]])flow[i^1]-=Low,flow[i]+=Low;
- LL tmp=ans;
- ans+=Low*dis[tt];
- if(ans>0){
- printf(”%I64d\n”,(0-tmp)/dis[tt]+Max_flow);
- flag=true;
- return false;
- }
- Max_flow+=Low;
- return true;
- }
- bool is_prime(LL x){
- LL px=(LL)sqrt((double)x);
- for(LL i=2;i<=px;i++)if(!(x%i))return false;
- return true;
- }
- int main(){
- freopen(”pair.in”,“r”,stdin);
- freopen(”pair.out”,“w”,stdout);
- memset(head,-1,sizeof head);
- scanf(”%I64d”,&n);
- for(LL i=1;i<=n;i++)scanf(“%I64d”,&a[i]);
- for(LL i=1;i<=n;i++){
- scanf(”%I64d”,&b[i]);
- sum+=b[i];
- }
- for(LL i=1;i<=n;i++)scanf(“%I64d”,&c[i]);
- for(LL i=1;i<=n;i++){
- LL tmp=a[i];
- LL tot=0;
- for(LL j=2;j<=tmp;j++){
- if(tmp%j==0){
- while(tmp%j==0){
- tmp/=j;
- tot++;
- }
- }
- }
- if((tot&1))
- lefts[i]=true;
- }
- for(LL i=1;i<=n;i++){
- for(LL j=i+1;j<=n;j++)
- if((a[i]%a[j]==0&&is_prime(a[i]/a[j]))||(a[j]%a[i]==0&&is_prime(a[j]/a[i]))){
- if(lefts[i])
- add(i,j,INF,-c[i]*c[j]);
- else
- add(j,i,INF,-c[i]*c[j]);
- }
- }
- for(LL i=1;i<=n;i++){
- if(lefts[i])
- add(ss,i,b[i],0);
- else
- add(i,tt,b[i],0);
- }
- while(BFS())if(!dfs())break;
- if(!flag)printf(“%I64d\n”,Max_flow);
- return 0;
- }
T3 游戏
【问题描述】
Alice 和 Bob 在玩一个游戏。
游戏在一棵有 n 个点的树上进行。
最初,每个点上都只有一个数字,那个数字是 123456789123456789。
有时,Alice 会选择一条从
对于路径上的一个点
有时,Bob 会选择一条从 s 到
他需要先从这条路径上选择一个点,再从那个点上选择一个数字。
Bob 选择的数字越小越好,但大量的数字让Bob 眼花缭乱。
Bob 需要你帮他找出他能够选择的最小的数字。
【输入格式】
第一行两个数字 n、
接下来 n−1 行,每行三个数字 u、v、w,表示树上有一条连接 u、v 的边,长度是 w。
接下来
若第一个数是 1,表示 Alice 进行操作,接下来四个数字
若第一个数是 2,表示 Bob 进行操作,接下来两个数字
【输出格式】
每当 Bob 进行操作,输出一行一个数,表示他能够选择的最小的数字。
【样例输入】
3 5
1 2 10
2 3 20
2 1 3
1 2 3 5 6
2 2 3
1 2 3 -5 -6
2 2 3
【样例输出】
123456789123456789
6
-106
【数据规模和约定】
【想法】
据说是搜索?
1591



被折叠的 条评论
为什么被折叠?



