8:30~12:00
20:00~21:30
写题组(周任务)
学习心得
1.一定注意看清题目,看清楚题目要求的输出
例如
给定一个数组A和一个目标值N,如果在数组中找到目标值则返回查找次数,如果没有则输出"NO."。
该题描述是若没有则输出"NO.";没错,不是NO,而是NO.,多了一个小数点,按照我们常规的方式去思考应该就是NO了,所以这是典型的想当然,做题一定得细心才行。题目还是不太难,简单的二分法就可以解决;
#include<stdio.h>
int a[100001],n,k;
void quicksort(int start,int end)
{
if(start>end)
return;
int i,j,t,temp;
temp=a[start];
i=start;
j=end;
while(i!=j)
{
while(a[j]>=temp&&j>i)
j--;
while(a[i]<=temp&&j>i)
i++;
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
a[start]=a[i];
a[i]=temp;
quicksort(start,i-1);
quicksort(i+1,end);
}
int main()
{
while(~scanf("%d",&n))
{
int i,count=0,t;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&k);
quicksort(1,n);//因为需要二分法,所以得排序
int start=1,end=n,mid;//这里的边界为数组长度
while(start<=end)
{
count++;//查找次数
mid=(start+end)/2;//二分求出中间值的下标
t=a[mid];//中间值
if(t>k)
end=mid-1;
else
if(t<k)
start=mid+1;
else
if(t==k)//查找到目标值后终止
break;
}
if(start<=end)//如果上面的循环被终止就代表查找到了目标元素
//若没有查找到目标元素的话start肯定是发育end的,否则循环还会继续
printf("%d\n",count);
else
printf("NO.\n");
}
return 0;
}
2.遇到难题要学会思考
例如
在我农场上有N头牛(1<=N<=50000),我想出了一个杂技特技:站到彼此上面,形成一个有一定高度的垂直堆叠,我就让这些牛来练习这个杂技,牛正在试图弄清楚它们应该在这堆奶牛中排列的顺序。每头N头牛具有相关的体重(1<=W_i<=10000)和强度(1<=S_i<=1000000000)。一头牛倒下的风险等于它身上所有牛的总体重(当然不包括它自己的体重)减去它的强度(这样一来,一头更强壮的牛的风险就更低)。你的任务是确定牛的顺序,使任何一头牛的最大风险最小化。
思考:对于这道题我一开始是完全没有思路的,这道题以前就看到过,当时也没有做出来。但是看到蛮多人做出来了自己肯定不想落后,所以我通过举例子推理发现了其中的一些小秘密,根据题意,设所有牛体重为w,第一头牛体重和力量分别为w1和s1,则其风险为w-s1+w1;第二头牛的体重为w2,力量为s2,则其风险为w-s2-w1-w2;
所以可以知道力量与体重之和越大,应该放在越下面。
有这个思路后现在就排序遍历就好了。
#include<stdio.h>
struct cows//定义一个结构体,r表示重量和力量之和
{
long long int w;
long long int s;
long long int r;
}id[50010];
int n;
void quicksort(int start,int end)
{
if(start>end)
return;
int i,j;
struct cows temp,t;
temp=id[start];
i=start;
j=end;
while(i!=j)
{
while(id[j].r>=temp.r&&i<j)
j--;
while(id[i].r<=temp.r&&i<j)
i++;
if(i<j)
{
t=id[i];
id[i]=id[j];
id[j]=t;
}
}
id[start]=id[i];
id[i]=temp;
quicksort(start,i-1);
quicksort(i+1,end);
}
int main()
{
while(~scanf("%d",&n))
{
long long int i,sum,risk;
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&id[i].w,&id[i].s);
id[i].r=id[i].w+id[i].s;
}
quicksort(1,n);
sum=0;
risk=sum-id[1].s;//从第一头牛开始算风险
//注:第一头牛是最顶上面的牛,也就是力量与体重之和最小的牛
sum=id[1].w;
for(i=2;i<=n;i++)
{
if(risk<sum-id[i].s)
risk=sum-id[i].s;
sum+=id[i].w;
}
printf("%lld\n",risk);
}
return 0;
}
3.学会耐心找出错误
例题
在我的生日派对上有N个饼,每个饼的大小不同,有许多朋友来参加我的生日派对,他们每一个人都得到了一块饼,如果其中有一个的饼比另一个人的大,他们就会抱怨,所以所有的饼应该分成相同的大小,当然了,我自己也要一块饼,而且那块也应该是同样的大小,我们所有人可能得到的最大尺寸的饼是多少?我做的饼都是圆柱形的,高度都是1,但是半径可以不一样。
分析:因为所有蛋糕的高度都是一,我们就只要判断面积是否相同就好了。找到其中最大的蛋糕所得到的值肯定是小于等于最大的蛋糕的,然后利用二分法去做
#include<stdio.h>
#define PI 3.14159265358//因为题目要精确到六位小数,所以PI的精度放大点
double V[10010];
int N,F;
int devide(double mid)//求当面积为mid时可以分多少个朋友
{
int count=0,i;
for(i=1;i<=N;i++)
count+=(int)(V[i]/mid);
return count;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&F);
double max=0,r;
int i;
F++;
for(i=1;i<=N;i++)
{
scanf("%lf",&r);
V[i]=r*r*PI;//将半径转化为体积
if(V[i]>max)
max=V[i];//求到最大的蛋糕
}
double min=0,mid;
while(max-min>1e-7)
{
mid=(max+min)/2.0;
int temp=devide(mid);
if(temp>=F)
min=mid;
else
if(temp<F)
max=mid;
}
printf("%.6lf\n",mid);
}
return 0;
}
em…然而答案还是错误,明天再去找找问题
一个半小时
黄云老师讲课
数据结构
算法
22:00~22:30
学习Java
目标
学会
定义接口
实现接口
接口继承