问题 C: 急眼的曹大神
内存限制:128 MB时间限制:1.000 S
题目描述
话说有这么一天, 曹大神正走在去上课的路上,突然他发现,似乎马上就要迟到了,急的他马上跳了起来(急的不能正常走路了 O(∩_∩)O哈哈~~)。现在假设曹大神的位置在(0,0),教室的位置在(x,0)。
曹大神第i次跳只能跳 i 的距离,帮曹大神算一下他最快能跳多少次就到教室,算对了曹大神可是会有感谢的哟~(每次跳跃可以向左也可以向右)
输入
输入一个整数 T,表示有 T 组测试数据。
对于每组测试数据,输入一个整数 x(-10e9 <= x <= 10e9)表示教室的x坐标。
输出
对于每组测试数据,输出一个整数,曹大神最快跳几次可以到教室。
样例输入 复制
3
2
6
0
样例输出 复制
3
3
0
提示
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
while(a--)
{
int n,sum=0,i=0;
scanf("%d",&n);
if(n==0)
{
printf("0\n");
continue;
}
else
{
if(n<0)
n=-n;
for( i=1;;i++)
{
sum+=i;
if(((sum-n)%2==0)&&sum-n>=0)
break;
}
printf("%d\n",i);
}
}
return 0;
}
问题 H: 背包问题-1(贪心)
内存限制:2 MB时间限制:1.000 S
题目描述
已知有一个可容纳重量为C的背包以及n件物品,其中第i件物品的重量为wi,每件物品的价值为pi(pi>0)。怎样向背包装如物品,才能使装入背包的物品的价值最大,编程求出最大价值(一件物品可以部分装入,部分装入是要合理、近似的装入,结果保留两位小数)。
输入
物品件数n
背包容量C
每件物品的重量和价值
输出
最大价值
样例输入 复制
3
30
20 40
15 25
15 25
样例输出 复制
56.66
#include<stdio.h>
int main()
{
float P=0;
int n,volum;
int w[1010],p[1010];//w是重量,p是价值
scanf("%d",&n);
scanf("%d\n",&volum);
for(int i=0;i<n;i++)
scanf("%d%d",&w[i],&p[i]);
for(int i=0;i<n-1;i++)
for(int j=0;j<n-1-i;j++)
if((double)p[j]/w[j]<(double)p[j+1]/w[j+1])
{
int t=p[j];
p[j]=p[j+1];
p[j+1]=t;
t=w[j];
w[j]=w[j+1];
w[j+1]=t;
}
int i=0;
for(int i=0;i<n;i++)
{
if(volum>=w[i])
{
volum-=w[i];
P+=p[i];
}
else
{
P+=(double)p[i]/w[i]*volum;
break;
}
}
printf("%.2f\n",(int)(P*100)/100.0);
}
问题 E: 逆序对(easy版)
内存限制:128 MB时间限制:1.000 S
题目描述
给定你一个长度为n的0/1序列a(只包含0和1),求逆序对的数量
逆序对:满足条件i<j并且a[i]>a[j]的i,j下标
输入
第一行给定一个t(1<=t<=1e3),表示有t组样例
对于每组样例,第一行给定一个n(1<=n<=5e6) 表示序列a的长度
第二行给定n个数,由0或1组成
保证对于每组数据中n的总和不超过5e6
输出
对于每组样例计算逆序对的数量
样例输入 复制
5
4
1 0 1 0
6
0 1 0 0 1 0
2
0 0
8
1 0 1 1 0 0 0 1
3
1 1 1
样例输出 复制
3
4
0
10
0
提示
答案可能超过int范围
补充知识点1
归并排序
#include<stdio.h>
#include<malloc.h>
void merge(int *arr,int left,int mid,int right)
{
int i=left;
int j=mid;
int *tmep=(int *)malloc((right-left)*4);
int index=0;
while(i<mid&&j<right)
{
if(arr[i]<arr[j])
tmep[index++]=arr[i++];
else
tmep[index++]=arr[j++];
}
while(i<mid)
tmep[index++]=arr[i++];
while(j<mid)
tmep[index++]=arr[j++];
for(int i=0;i<index;i++)
arr[left+i]=tmep[i];
free(tmep);
}
void mergesort(int *arr,int left,int right)
{
if(right-left<=1)
return ;
int mid=(left+right)/2;
mergesort(arr,left,mid);
mergesort(arr,mid,right);
merge( arr, left, mid, right);
}
int main()
{
int *arr1=(int*)malloc(4*4);
arr1[0]=10;
arr1[1]=9;
arr1[2]=8;
arr1[3]=7;
mergesort(arr1,0,4);
for(int i=0;i<4;i++)
printf("%d ",*arr1++);
}
补充知识点2
malloc函数
函数原型 void*malloc(size_t_Size)
需要#include<malloc.h>头文件
申请一段空间,并返回给空间的首地址
malloc(20) 申请一块20字节的空间
malloc(sizeof(int)*10) 申请10个int类型的数组(40个字节) int a[10]
但是我们定义的这块空间没有名字,只有一个首地址,所以说我们需要定义一个指针来指向这个首地址就可以使用了
int *p1=(int *)malloc(sizeof(int)*10)//返回类型为void*,我们要将其进行强制转化
与 int a[10]; int *p=a;这种写法基本一致,但是前置没有名字
使用完后我们使用free来释放malloc(或calloc、realloc)函数给指针变量分配的内存空间
最终代码
#include<stdio.h>
int n, arr[5000010],tmeparr[5000010];
unsigned long long count;
void merge_sort(int l, int r, int *arr)
{
if (l >= r) return ;
int mid = (l + r)/2;
merge_sort(l, mid, arr);
merge_sort(mid + 1, r, arr);
int pl = l, pr = mid + 1, tmpp = 0;
while(pl <= mid && pr <= r)
{
if (arr[pl] <= arr[pr])
tmeparr[tmpp++] = arr[pl++];
else
{ tmeparr[tmpp++] = arr[pr++];
count += mid - pl + 1;
}
}
while(pl <= mid)
tmeparr[tmpp++] = arr[pl++];
while(pr <= r)
tmeparr[tmpp++] = arr[pr++];
for (int i = 0; i < tmpp; i++)
arr[i + l] = tmeparr[i];
}
int main()
{
int a;
scanf("%d",&a);
while(a--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &arr[i]);
merge_sort(1, n, arr);
printf("%llu\n", count);
count=0;
}
return 0;
}