CSU-ACM2014暑假集训基础组训练赛(1) 解题报告

•Problem A HDU 4450                 水题,签到题
水题。。没啥好说的。给大家签到用的。
 1 #include <cstdio>
 2 int main(){
 3     int n,a,ans;
 4     while(scanf("%d",&n),n){
 5         ans = 0;
 6         for(int i = 0;i < n;i++){
 7             scanf("%d",&a);
 8             ans += a*a;
 9         }
10         printf("%d\n",ans);
11     }
12     return 0;
13 }
View Code

 

•Problem B Codeforces 230A     排序+贪心
题意:Kirito 要打n个怪兽,每个怪兽有两种属性(xi,yi),xi代表怪兽的力量,yi代表击败怪兽后可以为Kirito自己增加的力量。
初始时, Kirito有s力量,只有当Kirito的当前力量s比怪兽的力量xi的时候, Kirito才能击败这只怪兽i,同时,他自己的力量还将增加yi
你可以按任意顺序挑战这些怪兽,问Kirito最终能否击败所有的n只怪兽。
 
将n只怪兽的力量x按升序排列
假设Kirito当前挑战了一只他可以战胜的怪兽,且这只怪兽的力量不是最小的,那么他一定可以战胜那只力量更小的怪兽。
并且如果他先战胜了那只力量更小的怪兽,他在挑战这只当前怪兽的时候可以有更大的力量。
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 const int maxn = 1010;
 5 struct Dragon{
 6     int x,y;
 7     bool operator < (const Dragon &rhs) const{
 8         return x < rhs.x;
 9     }
10 }dragon[1010];
11 
12 int main(){
13     int s,n;
14     scanf("%d%d",&s,&n);
15     for(int i = 0;i < n;i++){
16         scanf("%d%d",&dragon[i].x,&dragon[i].y);
17     }
18     sort(dragon,dragon+n);
19     bool flag = 1;
20     for(int i = 0;i < n;i++){
21         if(s <= dragon[i].x){
22             flag = 0;
23             break;
24         }else{
25             s += dragon[i].y;
26         }
27     }
28     if(flag)    puts("YES");
29     else        puts("NO");
30     return 0;
31 }
View Code

 

•Problem C POJ 3258                   二分
题意:长为L(L<=10^9)的河上有N(N<=50,000)颗石头,除此之外,左岸和右岸还各有一块石头。它们在河上排成一条直线。每颗石头距离左岸石头的距离分别为Di。
现在让你拿走:除岸边2块石头外的任意M颗石头。你要使得剩下的石头(包括岸边的2块)它们之间的最短距离最大。
求这个最大的最短距离。
 
先将石头排序
最后的答案ans在[0,L]之间
二分答案ans
假设石头间的最短距离距离是ans,我们计算在该情况下需要拿走多少块(cnt)石头
如果cnt<=M 说明我们设定的最短距离可以更大
否则,我们设定的最短距离必须更小
O(NlogN)
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 const int maxn = 50010;
 5 int a[maxn],L,N,M;
 6 
 7 bool judge(int mid){
 8     int cnt = 0,last = 0;
 9     for(int i = 1;i <= N;i++){
10         if(a[i]-a[last] < mid){
11             cnt++;
12         }else{
13             last = i;
14         }
15     }
16     if(L - a[last] < mid)  cnt++;
17     return cnt <= M ? 1 : 0;
18 }
19 
20 int main(){
21     scanf("%d%d%d",&L,&N,&M);
22     for(int i = 1;i <= N;i++){
23         scanf("%d",&a[i]);
24     }
25     sort(a+1,a+N+1);
26     int l = 0,r = L,ans = 0;
27     while(l <= r){
28         int mid = (l+r)>>1;
29         if(judge(mid))  ans = mid,l = mid+1;
30         else    r = mid-1;
31     }
32     printf("%d\n",ans);
33     return 0;
34 }
View Code

 

•Problem D POJ 3984                   BFS
我们在bfs的时候,需要边bfs边记录路径
具体的来说,就是bfs到下一个点的时候,要记录它是通过谁走到这个点的
输出的时候要从终点反向寻找路径,用数组保存起来
最后将记录结果的数组反向输出
 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 
 5 const int dx[]={0, 1 ,0 ,-1} ;
 6 const int dy[]={1, 0 ,-1 ,0} ;
 7 int a[5][5] ,vis[5][5], fa[25], ans[25];
 8 
 9 int main()
10 {
11     for(int i=0;i<5;i++)
12         for(int j=0;j<5;j++)
13             cin>>a[i][j];
14     queue<int>Q;
15     Q.push(0) ;
16     vis[0][0] = 1 ;
17     while(!Q.empty()){
18         int u = Q.front(); Q.pop() ;
19         int x=u/5 , y = u%5;
20         for(int d=0; d<4; d++){
21             int nx = x + dx[d] , ny = y + dy[d];
22             if(nx<0 || nx>=5 || ny<0 || ny>=5 || vis[nx][ny] || a[nx][ny]) continue ;
23             int v = nx * 5 + ny ;
24             vis[nx][ny] = 1 , fa[v] = u ;
25             Q.push(v);
26         }
27     }
28     int p = 24 , top = 0 ;
29     while(true){
30         ans[top++] = p ;
31         if(p == 0) break;
32         p = fa[p];
33     }
34     while(top>0) {
35         --top ;
36         cout<<"("<<ans[top]/5<<", "<<ans[top]%5<<")"<<endl;
37     }
38     return 0;
39 }
View Code

 

•Problem E UVA 10036                DP
题意:给你N(1<=N<=10,000)个数字,你可以在它们之间的N-1个位置任意放“+”或“-”,放完之后,我们可以计算出表达式的值。
存不存在一种摆放方案使得最后表达式的值可以被K(1<=K<=100)整除
 
f[i][j]=1表示前i个数字形成的表达式的值除以K之后可以余j
f[0][0]=1
考虑第i个数字x,假设它是正的。
如果 f[i-1][j] = 1,说明前i-1个数字的表达式的值除以K可以余j
在x的前面放“+”, f[i][(j+x)%K] = 1
在x的前面放“-”,f[i][(j-x+K)%K]=1
 
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int N,K;
bool f[2][100];

int main()
{
    int T ;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d" , &N ,&K) ;
        memset(f , false , sizeof(f)) ;
        f[0][0] = true ;
        int cur = 0 , x ;
        for(int i=1; i<=N; i++){
            cur ^= 1 ;
            memset(f[cur] , false , sizeof(f[cur])) ;
            scanf("%d" , &x);
            if(i>1 && x<0) x = -x;
            x%=K;
            for(int u = 0; u<K; u++) if(f[cur^1][u]) {
                f[cur][(u+x+K)%K] = true;
                if(i>1) f[cur][(u-x+K)%K]=true;
            }
        }
        if(f[cur][0]) puts("Divisible") ;
        else puts("Not divisible") ;
    }
    return 0;
}
View Code

 

•Problem F Codeforces 229D      DP

题意:有n(1<=n<=5,000)座塔排在一条直线上,从左到右每个塔的高度分别为hi(1<=hi<=100,000),每次操作你可以选择一座塔(假设是第i座),用吊车把它吊起来,然后放到与它相邻的一座塔上(可以是第i-1座也可以是第i+1座),这样,新塔的高度为两座塔的和,完成操作后,塔的总数减少一座。问最少需要多少次操作可以使得所有的塔从左到右形成一个非递减序列。

解法:

dp(i)表示对前i座塔进行操作后形成非递减序列所需要的最小操作步数

last(i)表示在dp(i)最小的前提下,第i座塔的最低高度。

易知,将[i,j]区间内的塔合并成一座需要j-i步

于是我们得到dp方程:dp(i)=max{dp(j)+i-j+1| j<i, h(j+1)+h(j+2)+...+h(i-1)+h(i) <= last(j)}

注意,我们在递推的过程中要同时记录、更新last(j)的值来确保得到最优解。

 1 #include <cstdio>
 2 int dp[5010],sum[5010],last[5010];
 3 int main()
 4 {
 5     int n;
 6     scanf("%d",&n);
 7     for(int i = 1;i <= n;i++){
 8         int a;
 9         scanf("%d",&a);
10         sum[i] = sum[i-1]+a;
11         dp[i] = last[i] = 1<<30;
12     }
13     for(int i = 1;i <= n;i++){
14         for(int j = 0;j < i;j++){
15             if(sum[i]-sum[j] >= last[j] && dp[i] >= dp[j]+i-j-1){
16                 dp[i] = dp[j]+i-j-1;
17                 if(last[i] > sum[i]-sum[j]) last[i] = sum[i]-sum[j];
18             }
19         }
20     }
21     printf("%d\n",dp[n]);
22     return 0;
23 }
View Code

转载于:https://www.cnblogs.com/zhexipinnong/p/3851645.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的课程作业管理系,源码+数据库+开题报告+论文答辩+毕业论文+视频演示 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,课程作业管理系统当然也不能排除在外。课程作业管理系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用springboot框架构建的一个管理系统。整个开发过程首先对软件系统进行需求分析,得出系统的主要功能。接着对系统进行总体设计和详细设计。总体设计主要包括系统功能设计、系统总体结构设计、系统数据结构设计和系统安全设计等;详细设计主要包括系统数据库访问的实现,主要功能模块的具体实现,模块实现关键代码等。最后对系统进行功能测试,并对测试结果进行分析总结,得出系统中存在的不足及需要改进的地方,为以后的系统维护提供了方便,同时也为今后开发类似系统提供了借鉴和帮助。这种个性化的网上管理系统特别注重交互协调与管理的相互配合,激发了管理人员的创造性与主动性,对课程作业管理系统而言非常有利。 本课程作业管理系统采用的数据库是Mysql,使用springboot框架开发。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 1、关于课程作业管理系统的基本要求: (1)功能要求:可以管理首页、个人中心、公告信息管理、班级管理、学生管理、教师管理、课程类型管理、课程信息管理、学生选课管理、作业布置管理、作业提交管理、作业评分管理、课程评价管理、课程资源管理等功能模块。 (2)性能:在不同操作系统上均能无差错实现在不同类型的用户登入相应界面后能不出差错、方便地进行预期操作。 (3)安全与保密要求:用户都必须通过注册、登录才能进入系统,并且用户的权限也需要根据用户的类型进行限定。 (4)环境要求:支持多种平台,可在Windows系列、Vista系统等多种操作系统下使用。 关键词:课程作业管理系统,springboot框架; Mysql数据库 Java技术
毕业设计,基于SpringBoot+Vue+MySQL开发的旅游网站,源码+数据库+开题报告+论文答辩+毕业论文+视频演示 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势,旅游网站当然也不能排除在外,随着旅游网站的不断成熟,它彻底改变了过去传统的旅游网站方式,不仅使旅游管理难度变低了,还提升了旅游网站的灵活性。这种个性化的旅游网站特别注重交互协调经营与管理的相互配合,激发了管理人员的创造性与主动性,对旅游管理的管理而言非常有利。 本文首先分析了旅游网站的发展背景和意义,简要阐述了旅游网站系统开发的主要内容和优势,然后简要介绍了国内外旅游网站系统的研究和应用现状,并对系统开发技术,系统分析和总体设计,实现详细功能等。 本旅游网站系统采用的数据库是MySQL,使用Java技术开发,在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。 关键词:旅游网站;Java;SpringBoot; Vue; MySQL 数据库 旅游网站主要功能如下: 1.用户管理:注册、登录、退出、修改密码; 2.分类显示:显示旅游路线的分类; 3.旅游路线显示:按分类查询旅游路线、通过关键字搜索旅游路线、查看旅游路线的详细信息; 4.购物车管理:向购物车中添加旅游路线、修改购物车中旅游路线数量、删除购物车中旅游路线、我的购物车; 5.订单管理:通过购物车中生成订单、查看我的订单、查看某个订单的详细、订单支付、取消未付款订单。 6.首页:提供一个网站首页,该网站用户的登录,注册,所有旅游路线的一级分类,热门旅游路线和最新旅游路线的展示等。 7.旅游路线管理:旅游路线的上架、下架。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值