POJ1328(WA) 贪心只能过样例 结构体 sort()

关键词 :贪心 排序 结构体

 

一 题解

贪心这种题目真是尴尬……样例过了算法还是有可能不对

做贪心首先要证明正确性啊,感觉自己因为知道是贪心的题目,根本就没怎么考虑就开始做了,做完了发现自己的算法似乎不是对的……

找了一份题解,思路是和我一样的,按照x轴坐标排序之后,从最左边的点,开始计算,尽可能的使每次标记的雷达靠右。

链接:http://www.cnblogs.com/deliver/p/3330801.html

代码:

  1 #include <iostream>
  2 using namespace std;
  3 #include <math.h>
  4 
  5 struct island
  6 {
  7     int x;
  8     int y;
  9 };
 10 
 11 void quick_sort(island *islands,int start,int end,int d);
 12 int partition(island *islands,int start,int end,int d);
 13 bool smaller_than(island *is1,island *is2,int d);
 14 
 15 void sort(island *islands,int n,int d)
 16 {
 17     quick_sort(islands,0,n-1,d);
 18 }
 19 
 20 void quick_sort(island *islands,int start,int end,int d)
 21 {
 22     if(start>=end) return;
 23     int mid=partition(islands,start,end,d);
 24     quick_sort(islands,start,mid-1,d);
 25     quick_sort(islands,mid+1,end,d);
 26 }
 27 
 28 int partition(island *islands,int start,int end,int d)
 29 {
 30     int front,back,dir=0;
 31     island tis=islands[start];
 32     
 33     front=start;
 34     back=end;
 35     while(front<back)
 36     {
 37         if(dir==0)
 38         {
 39             if(!smaller_than(&tis,islands+back,d)){
 40                 islands[front].x=islands[back].x;
 41                 islands[front].y=islands[back].y;
 42                 front++;
 43                 dir=1;
 44             }
 45             else back--;
 46         }
 47         else 
 48         {
 49             if(smaller_than(&tis,islands+front,d)){
 50                 islands[back].x=islands[front].x;
 51                 islands[back].y=islands[front].y;
 52                 back--;
 53                 dir=0;
 54             }
 55             else front++;
 56         }
 57     }
 58     islands[front].x=tis.x;
 59     islands[front].y=tis.y;
 60     return front;
 61 }
 62 
 63 bool smaller_than(island *is1,island *is2,int d)
 64 {
 65     double v1=is1->x+sqrt(double(d*d-is1->y*is1->y)),v2=is2->x+sqrt(double(d*d-is2->y*is2->y));
 66     return v1<v2;
 67 }
 68 
 69 
 70 int place_radar(island *islands,int n,int d)
 71 {
 72     int i,counter=0;
 73     double rx,ry=0;
 74     i=0;
 75     while(i<n)
 76     {
 77         rx=islands[i].x+sqrt(double(d*d-islands[i].y*islands[i].y));
 78         counter++;
 79         i++;
 80         if(i>=n) break;
 81         while((rx-islands[i].x)*(rx-islands[i].x)+(ry-islands[i].y)*(ry-islands[i].y)<=d*d) 
 82         {
 83             i++;
 84             if(i>=n) break;
 85         }
 86     }
 87     return counter;
 88 }
 89 
 90 int main()
 91 {
 92     //freopen("data.txt","r",stdin);
 93 
 94     int i,n,d,counter=1,result;
 95 
 96     cin>>n>>d;
 97     while(n!=0||d!=0)
 98     {
 99         island *islands=new island[n];
100         for(i=0;i<n;i++) cin>>islands[i].x>>islands[i].y;
101 
102         bool flag=true;
103         for(i=0;i<n;i++) if(islands[i].y>d) {flag=false; break;}
104         if(d<0) flag=false;
105 
106         if(!flag) result =-1;
107         else{
108             sort(islands,n,d);
109             result=place_radar(islands,n,d);        
110         }
111 
112         cout<<"Case "<<counter<<": "<<result<<endl;
113         delete []islands;
114         counter++;
115         cin>>n>>d;
116     }
117 
118 
119     return 0;
120 }
AC代码

 

但是我仔细考虑了一下,是可以举出反例证明这种算法不正确的。

如果只有如下两个点的话,因为每次都尽可能地使安排的雷达的坐标靠右,所以对于这两个点按照上述算法是需要两个雷达的。但是事实上只要雷达的坐标稍微向左一点,就可以仅设置一个雷达就覆盖这两个点,所以该算法不成立。

至于上面的代码为什么可以AC……这就是个尴尬的问题了。

感觉自己的代码和上面的代码大同小异,但是就是一直WA,自己感觉也找不出来什么错了,所以就把代码贴出来,如果高手看到,帮我找找错吧,谢谢啦。

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <math.h>
 4 using namespace std;
 5 
 6 struct Point{
 7         int x;
 8         int y;
 9     //    int f;
10 };
11 
12 bool compare(Point a,Point b){
13     return a.x<b.x;
14 }
15 
16 int main()
17 {
18     Point p[1000];
19     int d,n,flag=0,m=0;
20     while(cin>>n>>d,n||d){
21         if (n==0&&d==0) exit(0);
22         flag=0;m++;
23         if (n==0) {cout<<"Case "<<m<<": "<<0<<endl;continue;}
24         if (d<0) {cout<<"Case "<<m<<": "<<-1<<endl;continue;}
25 
26         int i;
27         for(i=0;i<n;i++){
28             cin>>p[i].x>>p[i].y;
29             if((p[i].y>d)&&(p[i].y<0)) {flag=1;break;}
30      //       p[i].f=0;
31         }
32         if (flag) {cout<<"Case "<<m<<": "<<-1<<endl;continue;}
33 
34         sort(p,p+n,compare);
35         int ans=0;i=0;
36         double w,t;
37         while(i<n){
38             double hehe=d*d-p[i].y*p[i].y;
39             w=sqrt(hehe)+p[i].x;
40             i++;
41             ans++;
42             while(i<n){
43 
44                 t=(p[i].x-w)*(p[i].x-w)+p[i].y*p[i].y;
45                 if(t<=d*d){
46              //       p[i].f=1;
47                     i++;
48                 }else break;
49             }
50         }//while
51 
52         cout<<"Case "<<m<<": "<<ans<<endl;
53     }
54 
55     return 0;
56 }
My Answer

 

隔了一天又看了一个题解:

http://www.cnblogs.com/deliver/p/3330801.html

 

二 排序函数

  因为太久没撸这些代码了,所以好多小的知识点都忘了,我一点一点补充吧。

 

1 基本

  头文件:#include <algorithm>
  函数:sort(begin,end),表示升序排列一个范围,例如:

   int a[20]={2,4,1,23,5,76,0,43,24,65},i;
   for(i=0;i<20;i++) cout<<a[i]<<endl;
   sort(a,a+20);
   for(i=0;i<20;i++) cout<<a[i]<<endl;

 

2 降序排列

  一种是自己编写一个比较函数来实现,接着调用三个参数的sort:sort(begin,end,compare)就成了。对于list容器,这个方法也适用,把compare作为sort的参数就可以了,即:sort(compare).

1)自己编写compare函数:
bool compare(int a,int b){
  return a<b; //升序排列,如果改为return a>b,则为降序
}

 int a[20]={2,4,1,23,5,76,0,43,24,65},i;
 for(i=0;i<20;i++) cout<<a[i]<<endl;
 sort(a,a+20,compare);
 for(i=0;i<20;i++) cout<<a[i]<<endl;


3)其实对于这么简单的任务(类型支持“<”、“>”等比较运算符),完全没必要自己写一个类出来。标准库里已经有现成的了,就在functional里,include进来就行了。functional提供了一堆基于模板的比较函数对象。它们是(看名字就知道意思了):equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。对于这个问题来说,greater和less就足够了,直接拿过来用:

升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()).
int _tmain(int argc, _TCHAR* argv[])
{
  int a[20]={2,4,1,23,5,76,0,43,24,65},i;
  for(i=0;i<20;i++)
  cout<<a[i]<<endl;
  sort(a,a+20,greater<int>());
  for(i=0;i<20;i++)
  cout<<a[i]<<endl;
  return 0;
}

4)既然有迭代器,如果是string 就可以使用反向迭代器来完成逆序排列,程序如下:

#include <function>

int main()
{
  string str("cvicses");
  string s(str.rbegin(),str.rend());
  cout << s <<endl;
  return 0;
}

 

三 结构体(C++)

  C和C++中的结构体还是有一点点区别,具体不说了,下面是C++版的。

  1. 声明

struct Stu{

          int num;

          char name[20];      

}  

  2. 定义

 

  先声明后定义

         struct Stu{

                   int num;

                   char name[20];      

    };

          Stu s1,s2;

 

         声明同时定义

                  struct Stu{

             int num;

             char name[20];

      }st1,st2;

 

   3.结构体数组

      Stu a[10];

 

转载于:https://www.cnblogs.com/travelller/p/5730772.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值