这一场的排名是2,然而并没有什么卵用。
//头文件如下,ac代码全部省略头文件
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <algorithm>
#include <queue>
#include <deque>
#include <cstring>
#include <string>
#include <iostream>
#include <set>
#define ll long long
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
using namespace std;
*A题hdu2544
(不会做,事后学了Dijkstra算法,明天用floyd再写一遍)
题意:题目给出n,m分别为路口数量(1~n)和街道数量,街道包含三个元素:路口a,路口b,走过这条街道用的时间c,求问从路口1去到路口n最少需要多长时间。
题解:dijkstra套一套就好啦
ac代码:
int way[150][150],len[150],poi[150],n,m;
//way储存两路口之间的路,len是某个路口到路口1的距离,
//poi用来记录某路口是否被标记
int dijkstra(int n,int m)
{
for(int i=1;i<=n;i++)//初始化len
{
len[i]=way[i][1];
}
for(int i=1;i<=n-1;i++)
{
int minn=inf,u;
for(int j=1;j<=n;j++)
{
if(poi[j]==0&&len[j]<minn)
{
minn=len[j];
u=j;
}
}
poi[u]=1;
for(int j=1;j<=n;j++)
{
if(poi[j]==0&&(len[u]+way[u][j]<len[j]))
len[j]=len[u]+way[u][j];
}
}
return len[n];
}
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)break;
for(int i=1;i<=n;i++)
{
poi[i]=0;
for(int j=1;j<=n;j++)
if(i==j)way[i][j]=0;
else way[i][j]=inf;
}
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(w<way[u][v])way[u][v]=way[v][u]=w;
}
int ans=dijkstra(n,m);
printf("%d\n",ans);
}
return 0;
}
B题CSU - 1803
题意: 给出m和n,求满足条件:1:1≤a≤n,1≤b≤m;2:a×b 是 2016 的倍数的a和b的组数
题解:利用同余定理,取n(m)和2016间比较小的一个进入循环,对于某个a(b),它的所有同类数x都满足x=a+n*2016(n是任意实数,则x%2016==a%2016,因此可得
ac代码:
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
ll ans=0;
for(int i=1;i<=min(n,2016);i++)
{
for(int j=1;j<=min(m,2016);j++)
{
if((i*j)%2016==0)
{
ll a=n/2016,b=m/2016;
if(n%2016>=i)a++;
if(m%2016>=j)b++;
ans+=a*b;
}
}
}
printf("%lld\n",ans);
}
return 0;
}
C题究极水题
题意:给你一组数据,可以去掉任意一个数,求最大值和最小值的最小差
题解:原最大-新最小,新最大-原最小,取比较小的一个就好
ac代码:
int k[101000];
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&k[i]);
}
sort(k,k+n);
int a=k[n-1]-k[1],b=k[n-2]-k[0];
printf("%d\n",min(a,b));
return 0;
}
D题HDU5965
题意:给你一个3*n矩阵,第一行和第三行每个格子最多可以放一个地雷,第二行没有地雷,第二行每个格子显示一个数字,代表以该格为中心,周围8个格子的地雷总和
题解:这是个dp题,第一列的埋地雷情况会影响后续n-1列的情况,每一列可以埋地雷数为0,1,2,对应情况数为1,2,1;
令n[i]为每一列的地雷数,sum[i]为每一列的第二行记录的九宫格地雷总数:通过画图,我们可以发现,n[i]=sum[i-1]-n[i-1]-n[i-2](用别的表达方式也可以,是这个意思就行)
因此,只要枚举第一列地雷数为0,1,2的情况即可,中间要加上条件判断,防止数据有坑。
PS:记得模一下
char str[10100];
int s[10100],lie[10100];
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",str);
int n=strlen(str);
for(int i=0;i<n;i++)
s[i+1]=str[i]-'0';
//for(int i=1;i<=n;i++)printf("%d\n",s[i]);
s[0]=lie[0]=0;
ll ask=0;
for(int i=0;i<=2;i++)
{
if(i>s[1])break;
lie[1]=i;
int j;
for(j=2;j<=n;j++)
{
int a=s[j-1]-lie[j-1]-lie[j-2];
if(a>2||a<0)break;
lie[j]=a;//printf("**%d**%d\n",lie[j],j);
}
if(j<=n)continue;
if(s[n]!=lie[n-1]+lie[n])continue;
ll ans=1;
//for(int j=1;j<=n;j++)printf("*%d\n",s[j]);
for(int j=1;j<=n;j++)
{
if(lie[j]==0||lie[j]==2)ans=ans%mod;
else ans=(ans*2)%mod;//printf("*%d\n",s[j]);
//printf("**%lld--%d\n",ans,j);
}
ask=(ask+ans)%mod;//printf("**%lld\n",ask);
}
printf("%lld\n",ask);
}
return 0;
}
E题字符串题
题意:先给你一行句子,里面是各种动物的叫声,接下来告诉你除了狐狸以外所有动物的叫声,输出狐狸的叫声
题解:储存各种动物的叫声,与句子里的单词比较,进行删减
PSSSSSSSSSS:不要再把memset写成menset了!!!!!!!
char re[110][110];
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n;
scanf("%d",&n);//printf("%d",n);
while(n--)
{
getchar();
memset(re,0,sizeof(re));
char ch;
int i=0,j=0,mark[120]={0};
while((ch=getchar())!='\n')
{
if(ch!=' ')
{
re[i][j]=ch;
j++;
}
else {i++;j=0;}
//printf("%c",ch);
}
getchar();
int n=i+1;
while(1)
{
char a[120],b[120],c[120];
scanf("%s %s %s",a,b,c);//printf("%s %s %s\n",a,b,c);
if(!strcmp(a,"what")){scanf("%s %s",a,b);break;}
for(i=0;i<n;i++)
{
if(!strcmp(c,re[i])){//printf("check_000\n");
memset(re[i],0,sizeof(re[i]));mark[i]=1;
}
}
}
for(i=0;i<n;i++)
{
if(mark[i]==0)
{
printf("%s",re[i]);
if(i!=n-1)printf(" ");
}
}
printf("\n");
}
return 0;
}
//训练的时候写不出来,很烦,我讨厌字符串
//下面的代码是看了颖贤的代码之后写的,之后搞一下stl再做一次
F题CF545d
题意:队伍里面有n个客人,每个客人需要的服务时间是xi,每个客人等待的时间是wi,如果wi>xi,那么客人会不高兴,否则客人满意,请问在整理队列之后最多能让几个客人满意
题解:排序,维护一个sum,对比
ac代码:
int k[101000];
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&k[i]);
}
sort(k,k+n);
int ans=1,sum=k[0];
for(int i=1;i<n;i++)
{
if(k[i]>=sum)
{
ans++;
sum+=k[i];
}
}
printf("%d",ans);
return 0;
}
G题hdu5877
防ak题,先存着,以后补。
H题hdu6187
题意:给出n个塔楼和m个墙,给出塔楼的位置和城堡的位置,每一个墙连接接两个塔楼,拆墙需要对应的花费围为wi,在城堡里的国王需要用最小的花费拆掉最少的墙,以到达领土的任意地方,也就是说塔不能形成环(城堡无论是否在环内,都必定有去不了的地方,所以坐标完全没用=-=),求国王最少要拆多少墙,拆墙的最小花费是多少
题解:去除最少的边,且边的权值和最小,对应的是最大生成树。那么根据拆墙代价排序,然后去成圈的墙就好了
ac代码:
int pre[101000];
int found(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
bool uno(int x,int y)
{
int fx=found(x),fy=found(y);
if(fx!=fy){
pre[fx]=fy;return true;
}
else return false;
}
struct ppp
{
int a,b,c;
}poi[205000];
bool cmp(ppp x,ppp y)
{
return x.c>y.c;
}
int main()
{
#ifdef local
freopen("in.txt", "r", stdin);
#endif // local
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
//printf("一开始%d %d\n",n,m);
int x,y,cnt=0;
ll sum=0;
for(int i=1;i<=n;i++){pre[i]=i;scanf("%d%d",&x,&y);//printf("---%d %d\n",x,y);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&poi[i].a,&poi[i].b,&poi[i].c);//printf("**%d %d %d\n",poi[i].a,poi[i].b,poi[i].c);
}
sort(poi+1,poi+1+m,cmp);//for(int i=1;i<=m;i++)printf("**%d %d %d\n",poi[i].a,poi[i].b,poi[i].c);
for(int i=1;i<=m;i++)
{
if(!uno(poi[i].a,poi[i].b))
{
sum=sum+poi[i].c;//printf("%d %d %d\n",i,m-cnt,poi[i].c);
}
else cnt++;
}
printf("%d %lld\n",m-cnt,sum);
}
return 0;
}
收获:学了Dijskstra算法,学了最大生成树,没了。
今天也要加油ovo