2017
2017
2017 特长生
目录:
A.优美景点
B.益智游戏
C.工程
D.摆渡路线
A . A. A. 优美景点
分析:
排序然后输出
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
int T,a[505];
int main(){
freopen("landscape.in","r",stdin);
freopen("landscape.out","w",stdout);
scanf("%d",&T);
for(int i=1;i<=T;i++)
scanf("%d",&a[i]);
sort(a+1,a+T+1);
for(int i=T;i>=1;i--)
printf("%d\n",a[i]);
return 0;
}
B . B. B.益智游戏
分析:
搜索 注意可以一开始就添个负号
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
int T,a[6],qwq[6];
bool f;
void dfs(int dep,int sum)
{
if(f) return;
if(dep==4)
{
if(sum==24){
f=1;
return;
}
return;
}
for(int i=1;i<=4;i++)
{
if(!qwq[i])
{
qwq[i]=1;
dfs(dep+1,sum+a[i]);
dfs(dep+1,sum-a[i]);
dfs(dep+1,sum*a[i]);
if(sum%a[i]==0) dfs(dep+1,sum/a[i]);
if(sum!=0&&a[i]%sum==0) dfs(dep+1,a[i]/sum);
qwq[i]=0;
}
}
}
int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d",&T);
while(T--)
{
f=0;
memset(qwq,0,sizeof qwq);
for(int i=1;i<=4;i++)
scanf("%d",&a[i]);
for(int i=1;i<=4;i++)
{
if(!qwq[i])
{
qwq[i]=1;
dfs(1,-a[i]);
dfs(1,a[i]);
}
qwq[i]=0;
}
(f)?puts("1"):puts("0");
}
return 0;
}
C . C. C.工程
分析:
拓扑排序 i i i要等 j j j做完就是从 j j j到 i i i的边
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
const int N=205;
int n,w[N],x,in[N],tot,head[N],f[N],ans,vis[N];
queue<int> q;
struct node{
int to,next;
}a[N];
void add(int x,int y)
{
a[++tot]=(node){y,head[x]};
head[x]=tot;
}
int main(){
freopen("project.in","r",stdin);
freopen("project.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
{
scanf("%d",&x);
if(x==1)
{
add(j,i);
in[i]++;
}
}
for(int i=1;i<=n;i++)
if(!in[i])
{
f[i]=w[i];
q.push(i);
vis[i]=1;
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=a[i].next)
{
int qwq=a[i].to;
if(!vis[qwq])
{
f[qwq]=max(f[qwq],f[x]);
in[qwq]--;
if(!in[qwq])
{
f[qwq]+=w[qwq];
vis[qwq]=1;
q.push(qwq);
}
}
}
}
for(int i=1;i<=n;i++)
{
if(in[i]>0)
{
puts("-1");
return 0;
}
else ans=max(ans,f[i]);
}
printf("%d",ans);
return 0;
}
D . D. D.摆渡路线
分析:
先破环成链 设
f
i
,
j
f_{i,j}
fi,j表示
i
i
i到
j
j
j的最多保留的线路
枚举中间点
k
k
k 那么就是个区间
d
p
dp
dp 最后在加上两点间是否本来有
答案就是
f
i
,
i
+
100
−
1
f_{i,i+100-1}
fi,i+100−1
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
typedef long long ll;
const int N=205;
int T,f[N][N],qwq[N][N],ans;
int main(){
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
scanf("%d",&T);
for(int i=1,x,y;i<=T;i++)
{
scanf("%d%d",&x,&y);
if(x>y) swap(x,y);
qwq[x][y]=1;
qwq[x+100][y+100]=1;
}
for(int len=1;len<=100;len++)
for(int i=1;i+len-1<=200;i++)
{
int j=i+len-1;
for(int k=i;k<=j;k++)
f[i][j]=max(f[i][j],f[i][k]+f[k][j]);
f[i][j]+=qwq[i][j];
}
for(int i=1;i<=100;i++)
ans=max(ans,f[i][i+100-1]);
printf("%d",ans);
return 0;
}