HDU4310_acm_Hero

Problem Description
When playing DotA with god-like rivals and pig-like team members, you have to face an embarrassing situation: All your teammates are killed, and you have to fight 1vN.

There are two key attributes for the heroes in the game, health point (HP) and damage per shot (DPS). Your hero has almost infinite HP, but only 1 DPS.

To simplify the problem, we assume the game is turn-based, but not real-time. In each round, you can choose one enemy hero to attack, and his HP will decrease by 1. While at the same time, all the lived enemy heroes will attack you, and your HP will decrease by the sum of their DPS. If one hero's HP fall equal to (or below) zero, he will die after this round, and cannot attack you in the following rounds.

Although your hero is undefeated, you want to choose best strategy to kill all the enemy heroes with minimum HP loss.
 

Input
The first line of each test case contains the number of enemy heroes N (1 <= N <= 20). Then N lines followed, each contains two integers DPSi and HPi, which are the DPS and HP for each hero. (1 <= DPSi, HPi <= 1000)
 

Output
Output one line for each test, indicates the minimum HP loss.
 

Sample Input
  
  
1 10 2 2 100 1 1 100
 

Sample Output
  
  
20 201

本题提供两种语言的解决方案,首先参考网上的C代码写出了注释版的C代码,再把它转化为了Java代码。

在转化中发现C与Java的区别还是挺大的,但是既然为一个算法题,能用C解决的就一定也能用Java,只不过是实现的方法不尽相同罢了,原理还是共通的。

C中使用结构体的方法定义了Hero的数据类型,而Java中是使用类Class的方法定义Hero;

C中排序的方法是用类库中的sort()函数,而Java则需要实现Comparator接口了,通过Arrays中的sort()方法对对象排序;

在排序函数/方法的编写中,两者的区别在于C中使用指针来传参数,Java通过中间变量Object 传递,返回的类型与计算方法一样。


本题的方法: 先对Hero对象数组进行排序,按照优先攻击的顺序排序。 排序方法是 DPSi / HPi 的大小,越大的攻击优先级越高。

对结构体或者Java中的对象进行排序,可以使用类库中带的排序方法。对于C是sort ,对于Java则是调用Arrays中的sort。

其中排序的规则,C是自己写一个函数作为sort的参数即可,Java需要实现comparator接口,再将其作为参数传递到sort即可。

排序完成三个for循环,第一个循环  从0-N 把所有存活的Hero循环一遍

第二个循环  把所有HP>0的Hero.HPi 减 1 循环

第三个循环  每次把剩下的Hero(即第一个循环的 i 变量)

最后把每次造成的伤害累加到sum中

		//快速排序 四个参数
		//1.待排序数组首地址
		//2.数组中待排序元素数量
		//3.各元素占用空间大小
		//4.指向函数的指针,用于确定排序的顺序
		//对结构体进行排序

#include<stdio.h>
#include<stdlib.h>
struct In{
	double bi;
	int dps;
	int hp;
}hero[100];
int cmp(const void *a,const void *b){
	//比较函数
	struct In *c = (In*)a;
	struct In *d = (In*)b;
	/*
	(a->dps / a->hp) - (b->dps / b->hp) 
	a->dps * b->hp - b->dps * a->hp
	-------------------------------- 
	a->hp * b->hp
	
	计算机除法会出现数据不准确,不可预知的错误
	所以改成乘法可以正确运行
	*/
	return (d->dps * c->hp - c->dps * d->hp);
}

int main(){
	int n,i,j,k;
	int sum;
	while (scanf("%d",&n) != EOF ){ //要输入的数据条数
		for(i=0; i<n; i++){
			scanf("%d %d",&hero[i].dps,&hero[i].hp);
			//转换成浮点数
			//hero[i].bi = hero[i].dps * 1.000 / hero[i].hp * 1.000;
		}
		qsort(hero, n, sizeof(hero[0]),cmp); 
		sum = 0;
		for(i=0; i<n; i++){//输入的n个数据
			for(j=hero[i].hp; j>0; j--){//每个数据的 生命值减一枚举
				for(k=i; k<n; k++){//i--n 所有存活的伤害累加
					sum = sum + hero[k].dps;
				}//for3
			}//for2
		}//for1
		//输出伤害
		printf("%d\n",sum);
	
	}//end while
	return 0;
}//end main
JAVA代码
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
public class Main {
    
    public static void main(String[] args) {
    	//输入
    	Scanner sc = new Scanner(System.in);
   		int N = sc.nextInt();
    	Hero[] hero = new Hero[N];
    	ArrayList arrayList = new ArrayList();
    	for(int i=0; i<N; i++){
    		hero[i] = new Hero();
    		hero[i].DPSi = sc.nextInt(); 
    		hero[i].HPi  = sc.nextInt();	
    		arrayList.add(hero[i]);
    	}
    	
    	//排序
    	Arrays.sort(hero,0,N-1,new Com_hero());
    	
    	//计算输出
    	int DSP_Count = 0;
    	for(int i=0; i<N; i++){
    		//
    		for( ; hero[i].HPi>0; hero[i].HPi --){
    			//
    			for(int k=i; k<N; k++){
    				DSP_Count += hero[k].DPSi;
    			}
    		}
    	}
    	System.out.println(DSP_Count);
    	
    }
}
//对象声明
class Hero{
	int HPi;
	int DPSi;
	Hero(){}
}
class Com_hero implements Comparator{
	public int compare(Object com1,Object com2){
		Hero h1 = (Hero)com1;
		Hero h2 = (Hero)com2;
		if(h1.DPSi * h2.HPi < h2.DPSi * h1.HPi )
			return 1;
		else return -1;		
	}
}




#include"stdio.h"
#include"string.h"
#include"stdlib.h"
struct A
{
	int t,v;
}E[30];
int cmp(const void *a,const void *b)
{
	A *c,*d;
	c=(A *)a;
	d=(A *)b;
	return (c->t*d->v)-(d->t*c->v);
}

int main()
{
	int n;
	int i,l;
	int base,ans;
	while(scanf("%d",&n)!=-1)
	{
		base=0;
		for(i=0;i<n;i++)	{scanf("%d%d",&E[i].v,&E[i].t);base+=E[i].v;}
		qsort(E,n,sizeof(E[0]),cmp);

		ans=0;
		for(i=0;i<n;i++)
		{
			ans+=base*E[i].t;
			base-=E[i].v;
		}
		printf("%d\n",ans);
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是hdu4310的Java解法: ```java import java.util.*; import java.io.*; public class Main { static int MAXN = 100010; static int MAXM = 200010; static int INF = 0x3f3f3f3f; static int n, m, s, t, cnt; static int[] head = new int[MAXN]; static int[] dis = new int[MAXN]; static boolean[] vis = new boolean[MAXN]; static int[] pre = new int[MAXN]; static int[] cur = new int[MAXN]; static class Edge { int to, next, cap, flow, cost; public Edge(int to, int next, int cap, int flow, int cost) { this.to = to; this.next = next; this.cap = cap; this.flow = flow; this.cost = cost; } } static Edge[] edge = new Edge[MAXM]; static void addEdge(int u, int v, int cap, int flow, int cost) { edge[cnt] = new Edge(v, head[u], cap, flow, cost); head[u] = cnt++; edge[cnt] = new Edge(u, head[v], 0, 0, -cost); head[v] = cnt++; } static boolean spfa() { Arrays.fill(dis, INF); Arrays.fill(vis, false); Queue<Integer> q = new LinkedList<>(); q.offer(s); dis[s] = 0; vis[s] = true; while (!q.isEmpty()) { int u = q.poll(); vis[u] = false; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) { dis[v] = dis[u] + edge[i].cost; pre[v] = u; cur[v] = i; if (!vis[v]) { vis[v] = true; q.offer(v); } } } } return dis[t] != INF; } static int[] MCMF(int s, int t) { int flow = 0, cost = 0; while (spfa()) { int f = INF; for (int u = t; u != s; u = pre[u]) { f = Math.min(f, edge[cur[u]].cap - edge[cur[u]].flow); } for (int u = t; u != s; u = pre[u]) { edge[cur[u]].flow += f; edge[cur[u] ^ 1].flow -= f; cost += edge[cur[u]].cost * f; } flow += f; } return new int[]{flow, cost}; } public static void main(String[] args) { Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in))); int T = in.nextInt(); for (int cas = 1; cas <= T; cas++) { n = in.nextInt(); m = in.nextInt(); s = 0; t = n + m + 1; cnt = 0; Arrays.fill(head, -1); for (int i = 1; i <= n; i++) { int c = in.nextInt(); addEdge(s, i, c, 0, 0); } for (int i = 1; i <= m; i++) { int c = in.nextInt(); addEdge(i + n, t, c, 0, 0); } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { int c = in.nextInt(); addEdge(i, j + n, INF, 0, c); } } int[] ans = MCMF(s, t); System.out.printf("Case #%d: %d\n", cas, ans[1]); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值