#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXN 100005 #define inf 0x7fffffff int a1[4],a2[4],T; double mx1[MAXN],mx2[MAXN]; double min(double a,double b) { return a<b?a:b; } int main() { for(int i=1;i<=3;++i) scanf("%d",&a1[i]); for(int i=1;i<=3;++i) scanf("%d",&a2[i]); scanf("%d",&T); double l=0,r=inf; for(int TTT=1;TTT<=100;++TTT) //100次迭代,不同的题可能需要更多迭代次数 { double mid=(l+r)/2; for(int i=1;i<=3;++i) mx1[i]=a1[i]*mid,mx2[i]=a2[i]*mid; if(mx1[1]+mx2[1]>=200 && mx1[2]+mx2[2]>=300 && mx1[1]+mx2[1]+mx1[2]+mx2[2]<=T*1.0) //满足条件 { printf("%.0lf %.0lf %.0lf",mx1[1]+mx2[1],mx1[2]+mx2[2],mx1[3]+mx2[3]); break; } if(mx1[1]+mx2[1]<200 || mx1[2]+mx2[2]<300 || mx1[1]+mx2[1]+mx1[2]+mx2[2]>T*1.0) l=mid; else r=mid; } return 0; }优化上述代码
时间: 2024-04-06 07:34:40 浏览: 18
这段代码本身已经比较简洁,但可以考虑以下几点优化:
1. 使用变量保存常量
将 inf 和 100 这两个常量定义为变量,可以避免代码中的魔法数字,提高代码可读性。
2. 减少重复代码
将读入 a1 和 a2 数组的循环合并,可以减少重复代码。
3. 使用二分查找优化循环次数
由于题目要求找到最小的满足条件的值,可以使用二分查找来优化循环次数,避免不必要的计算。
4. 减少计算次数
将 mx1 和 mx2 的计算提出来,避免在循环中多次计算,提高效率。
优化后的代码如下:
相关问题
#include<stdio.h> #include<math.h> int main() { int N,m; do{ scanf("%d",&N); }while(N<=1); printf("2 "); for(m=3;m<=N;m++){ int i; int tmp=(int)sqrt(m); for(i=2;i<=m;i++) if(m%i==0) break; if(i>tmp) printf("%d ",m); } return 0; } 优化该代码
上述代码是朴素的暴力枚举法,每次判断一个数是否为素数时都需要从2到该数的平方根进行循环,时间复杂度为O(n*sqrt(n)),效率较低。下面介绍两种优化方法:
1. 埃氏筛法优化
我们可以使用埃氏筛法来优化。具体做法是:首先定义一个长度为N+1的数组is_prime[],其中is_prime[i]表示i是否是素数,初始时全部初始化为true。然后从2开始枚举每个素数i,将i的倍数j(j≥2且i*j≤n)标记为合数,即令is_prime[i*j]=false。最后输出所有is_prime[i]为true的i,即为小于等于n的所有素数。时间复杂度为O(n*loglog(n)),效率更高。
下面是优化后的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#define MAXN 1000000
int main()
{
int n;
bool is_prime[MAXN + 1] = {false}; // 初始化为false
scanf("%d", &n);
printf("2 ");
for (int i = 3; i <= n; i += 2) // 从3开始,每次加2
{
if (!is_prime[i])
{
printf("%d ", i);
for (int j = i * i; j <= n; j += 2 * i) // 从i的平方开始标记,每次加2*i
{
is_prime[j] = true;
}
}
}
return 0;
}
```
2. 埃氏筛法进一步优化
在埃氏筛法的基础上,我们还可以进一步优化,减少时间和空间的使用。具体做法是:首先定义一个长度为N+1的数组is_prime[],其中is_prime[i]表示i是否是素数,初始时全部初始化为true。然后从2开始枚举每个素数i,将i的倍数j(j≥2且i*j≤n)标记为合数,即令is_prime[i*j]=false。最后输出所有is_prime[i]为true的i,即为小于等于n的所有素数。
优化的关键在于:对于一个素数i,它的倍数2i、3i、4i、……已经被之前的素数标记过了,因此,在枚举素数i时,我们可以从i的平方开始标记,而不是从2i开始标记。这样可以减少一半的标记次数。
下面是优化后的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#define MAXN 1000000
int main()
{
int n, cnt = 0;
bool is_prime[MAXN + 1] = {false}; // 初始化为false
scanf("%d", &n);
printf("2 ");
for (int i = 3; i <= n; i += 2) // 从3开始,每次加2
{
if (!is_prime[i])
{
printf("%d ", i);
cnt++;
if (cnt % 10 == 0) // 每10个数换行
{
printf("\n");
}
for (int j = i * i; j <= n; j += 2 * i) // 从i的平方开始标记,每次加2*i
{
is_prime[j] = true;
}
}
}
return 0;
}
```
#include <stdio.h> #include <time.h> #include <stdlib.h> #include <math.h> #include <smmintrin.h> #include <emmintrin.h> #include <immintrin.h> #define MAXN 100000000 float a[MAXN]; float b[MAXN]; float c[MAXN]; float d[MAXN]; int main() { for (int i = 0; i < MAXN; ++i) { a[i] = 1.0 / (rand() + 1); b[i] = 1.0 / (rand() + 1); } for (int n = 0; n < 20; ++n) { for (int i = 0; i < MAXN; ++i) { d[i] += a[i] * b[i]; } } clock_t start, end; start = clock(); for (int i = 0; i < MAXN; i += 8) // 假设MAXN是8的倍数 { __m256d va = _mm256_load_pd(&a[i]); // 加载8个双精度浮点数到寄存器 __m256d vb = _mm256_load_pd(&b[i]); __m256d vc = _mm256_load_pd(&c[i]); __m256d result = _mm256_mul_pd(va, vb); // 向量乘法运算 result = _mm256_add_pd(result, vc); // 向量加法运算 _mm256_store_pd(&c[i], result); // 存储结果回内存 } end = clock(); printf("time=%f\n", (double)(end - start) / CLOCKS_PER_SEC); for (int i = 0; i < MAXN; ++i) { if (fabs(c[i] - d[i]) / d[i] > 0.0001) { printf("Check Failed at %d\n", i); return 0; } } printf("Check Passed"); } 34 38 C:\Users\Administrator\Desktop\add.cpp [Error] cannot convert 'float*' to 'const double*' for argument '1' to '__m256d _mm256_load_pd(const double*)'
这段代码出现了一个错误。错误的原因是在使用SSE指令集进行向量化计算时,加载数据时使用了错误的数据类型。在这段代码中,数组a、b、c、d的数据类型是float,但是在使用`_mm256_load_pd`函数加载数据时,需要传入`const double*`类型的参数。因此,需要将加载数据的部分修改为使用`_mm256_load_ps`函数来加载单精度浮点数。同时,由于AVX指令集对齐要求更高,需要确保数组a、b、c、d的地址是16字节对齐的。
以下是修改后的代码:
```cpp
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <smmintrin.h>
#include <emmintrin.h>
#include <immintrin.h>
#define MAXN 100000000
float a[MAXN];
float b[MAXN];
float c[MAXN];
float d[MAXN];
int main()
{
for (int i = 0; i < MAXN; ++i)
{
a[i] = 1.0 / (rand() + 1);
b[i] = 1.0 / (rand() + 1);
}
for (int n = 0; n < 20; ++n)
{
for (int i = 0; i < MAXN; ++i)
{
d[i] += a[i] * b[i];
}
}
clock_t start, end;
start = clock();
for (int i = 0; i < MAXN; i += 8) // 假设MAXN是8的倍数
{
__m256 va = _mm256_load_ps(&a[i]); // 加载8个单精度浮点数到寄存器
__m256 vb = _mm256_load_ps(&b[i]);
__m256 vc = _mm256_load_ps(&c[i]);
__m256 result = _mm256_mul_ps(va, vb); // 向量乘法运算
result = _mm256_add_ps(result, vc); // 向量加法运算
_mm256_store_ps(&c[i], result); // 存储结果回内存
}
end = clock();
printf("time=%f\n", (double)(end - start) / CLOCKS_PER_SEC);
for (int i = 0; i < MAXN; ++i)
{
if (fabs(c[i] - d[i]) / d[i] > 0.0001)
{
printf("Check Failed at %d\n", i);
return 0;
}
}
printf("Check Passed");
return 0;
}
```
请注意,我对加载数据和存储结果的部分进行了修改,并将数据类型从`__m256d`改为了`__m256`,以适应单精度浮点数。另外,代码中的对齐问题需要注意,可以使用`posix_memalign`或`_aligned_malloc`等方法来确保数组的对齐。