sort(HDU-3293)

武器排序算法
本文介绍了一个用于对武器进行排序的算法,该算法首先按照武器的来源地进行字母序排序,对于同一来源地的武器再根据其威力等级从高到低排序,若等级相同则继续按名称的字母序排序。
Problem Description
As is known to all, long long ago sailormoon once was an association of fighters. Till now, sailormoon is also an association of girls. Owe to some unknown reasons, girls are necessary to fight for peace.
Their boss, lcy, wants to strengthen their ability, so he give them his precious collections---weapons for many years. Because these collections are really age-old, it is hard to recognize from one to another. So girls intend to sort them before they use. Each weapon has its name, origin and level of harmfulness ( level contains three ranks: wonderful, good, so-so).
In order to make it clear, girls want to sort like this:
firstly,sort according to the origin (sort by lexicographic order), if two or more have the same origin, they will be sorted together;
secondly, sort according ranks, wonderful is the best, good is next, the third is so-so;
thirdly, if two or more have same origin and rank, sort them according to the lexicographic order.


 

Input
Input contains multiply cases. Each case contains several lines. First line is an integer N(0<N<=500), representing the number of weapons. Then N lines follows. Each line represent a kind of weapon, and contains a set of strings representing name, origin and level of harmfulness. 
Each string will not exceed 20 characters.
Sure that same origin will not exist the same weapon.
 

Output
Please output your list after sorting (format according to sample, pay attention to the spaces,ten spaces need ^ ^).
 

Sample Input
5 knife qizhou so-so gun qizhou wonderful knife zhengzhou good stick zhengzhou good rope shengzhou so-so
 

Sample Output
Case 1 qizhou: gun wonderful knife so-so shengzhou: rope so-so zhengzhou: knife good stick good
 
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct pp
{
    string ori,na,le;
    int l;
};
pp p[510];
bool cmp(const pp&a,const pp&b)
{
    if(a.ori!=b.ori)
        return a.ori<b.ori;
    else if(a.l!=b.l)
        return a.l<b.l;
    else
        return a.na<b.na;
}
set<string>origin;
int main()
{
    int n,t=1;
    while(cin>>n)
    {
        string a,b,c;
        for(int i=0;i<n;i++)
        {
            cin>>p[i].na>>p[i].ori>>p[i].le;
            origin.insert(p[i].ori);
            if(p[i].le[0]=='w')
                p[i].l=1;
            else if(p[i].le[0]=='g')
                p[i].l=2;
            else
                p[i].l=3;
        }
        int l=0;
        sort(p,p+n,cmp);
        cout<<"Case "<<t<<endl;
        for(set<string>::iterator it=origin.begin();it!=origin.end();it++)
        {
            cout<<*it<<":\n";
            for(;l<n&&*it==p[l].ori;l++)
                cout<<"          "<<p[l].na<<" "<<p[l].le<<endl;
        }
        t++;
        origin.clear();
    }
    return 0;
}


### HDU 4393 抛钉子 C++ 实现与算法思路 #### 算法分析 针对 HDU 4393 的问题,可以采用三种不同的方法来解决问题。以下是每种方法的具体描述及其背后的逻辑。 1. **基于时间分段的排序策略** 如果考虑 `Fi` 最大值为 500,则在超过 501 秒的时间范围内,速度 `Si` 将成为决定排名的主要因素。因此,在此时间段内,可以通过简单的排序操作完成最终排名计算[^2]。具体而言: - 在前 501 秒内通过暴力方式逐一模拟每个选手的状态变化。 - 排序依据:当 `t &gt;= 501` 时,若两个选手的 `Fi` 相同,则比较其 ID;否则仅需关注 `Si` 即可得出最终排名。 2. **利用二维单调性优化搜索过程** 若路径长度 `way` 和速度 `speed` 构成了一组二维不递增序列,则该条件下各选手之间的相对位置关系保持不变。这意味着一旦发现某时刻满足上述特性,后续无需再继续更新状态而可以直接输出当前结果。这种方法减少了不必要的迭代次数从而提高了效率。 3. **优先队列辅助下的动态规划方案** 鉴于题目设定中提到的最大初始力量值不超过 100 (`S_i &le; 100`) ,我们能够构建一系列大小固定的小型优先队列用于管理不同类别下可能获胜者的信息集合。这些小型优先队列分别存储具有特定初速等级的所有参赛人员数据,并按照各自的第一关键属性即剩余力场强度以及次级区分标准如编号来进行排列整理工作流程如下所示: - 初始化阶段创建若干个独立运作但相互关联紧密程度较高的专用容器结构体实例对象; - 每轮循环期间从各个活跃中的候选池子里挑选出符合条件的最佳选项加以处理直至结束为止。 #### 示例代码实现 (Method One) 下面提供了一个基于第一种解决方案编写而成的有效程序版本: ```cpp #include &lt;bits/stdc++.h&gt; using namespace std; struct Player { int id; int f; // force int s; // speed }; bool cmp(const Player &amp;a, const Player &amp;b){ if(a.f != b.f) return a.f &gt; b.f; else return a.id &lt; b.id; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int T; cin &gt;&gt; T; while(T--){ int n,t; cin&gt;&gt;n&gt;&gt;t; vector&lt;Player&gt; players(n); for(int i=0;i&lt;n;++i){ players[i].id=i+1; cin&gt;&gt;players[i].f&gt;&gt;players[i].s; } if(t&lt;=501){ sort(players.begin(), players.end(), [&amp;](const Player&amp; p1,const Player&amp; p2)-&gt;bool{ long long w1=(long long)p1.s*(t-1)+p1.f; long long w2=(long long)p2.s*(t-1)+p2.f; if(w1!=w2)return w1&gt;w2; else return p1.id&lt;p2.id; }); } else{ // t&gt;501 sort(players.begin(), players.end(),cmp); } for(auto &amp;player : players){ cout&lt;&lt;player.id&lt;&lt;&quot; &quot;; } cout&lt;&lt;&quot;\n&quot;; } } ``` #### 结论 以上介绍了三种适用于解决 HDU 4393 &ldquo;Throw Nails&rdquo; 问题的不同技术手段及其相应的理论基础说明文档内容摘录自参考资料部分所提及之处^。开发者可以根据实际需求选择最适合自己的那一款进行编码实践测试验证效果如何!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值