B - Math Show CodeForces - 846B

本文介绍了一个算法问题:给定n个任务,每个任务包含k个子任务及各自所需时间,目标是在限定时间内通过合理安排获得最大积分。文章通过枚举判断的方法实现这一目标。

n个任务每个任务里有k个子任务,每个子任务完成需要a[i]个时间,完成一个子任务积一分,完成大任务多积一分。

总时间为m,求最大积分数。枚举判断即可

#include<cstdio>
#include<algorithm>
using namespace std;
int a[50];

int main(){
	int n,k,m;
	while(~scanf("%d%d%d",&n,&k,&m)){
		int sum=0;
		for(int i=0;i<k;i++){
			scanf("%d",&a[i]);
			sum+=a[i];
		}
		sort(a,a+k);
		int ans=0,res;
		for(int i=0;i<=n;i++){
			res=i*sum;
			if(res>m) break;
			int tmp=res;
			int score=i*(k+1);
			for(int j=0;j<k;j++){
				for(int t=i+1;t<=n;t++){
					tmp+=a[j];
					score++;
					if(tmp>m){
						score--;
						j=k;
						break;
					}
				}
			}
			ans=max(ans,score);
		}
		printf("%d\n",ans);
	}
	return 0;
} 

 

#include <stdio.h> #include <stdbool.h> #include <math.h> #include <string.h> //E2H! //long long arrp[200020]; //定义存储0和1状态的数组 //long long fd[200020]; //定义存储首次满足需要天数的数组 //bool found[200020] = { false };//定义bool存储该数据是否被读取过 //E2F! int n, d[100500], a[100500], e[100500], z1[100500]; int main(void) { //C2A //printf("#include<stdio.h>\n"); //printf("int main() {\n"); //printf(" int a, b, sum;\n"); //printf(" scanf(\"%%d%%d\", &a, &b);\n"); //printf(" sum = a + b;\n"); //printf(" printf(\"%%d + %%d = %%d\", a, b, sum);\n"); //printf(" return 0;\n"); //printf("}"); //return 0; //C2B //int a; //while (scanf_s("%d", &a) != EOF) //{ // char A =a; // if (A >= '0' && A <= '9'|| A >= 'A' && A <= 'Z'|| A >= 'a' && A <= 'z') // { // printf("Lingliang likes %c!\n",A); // } // else printf("Ewww\n"); //} //return 0; //C2C //int n; //double a; //double pi = 3.14159265358979; //scanf_s("%d",&n); //for (int i = 0; i < n; i++) //{ // scanf_s("%lf", &a); // printf("%.4lf\n", 2 * pi * a); //} //return 0; //C2D //long long n,a; //long long arr[2000]; //scanf_s("%lld", &n); //for (int i = 0; i < n; i++) //{ // scanf_s("%lld",&a); // arr[i] = a; //} //for (int j = 0; j < n; j++) //{ // printf("%lld ", arr[n-1-j]); //} //return 0; //C2E //int n, x, k=0; //int a; //int arr[1000]; //scanf_s("%d%d", &n, &x); //for (int i = 0; i < n; i++) //{ // scanf_s("%d",&a); // arr[i] = a; //} //for (int j = 0; j < n; j++) //{ // if (arr[j] > x) // { // k++; // } //} //printf("%d", k + 1); //return 0; //C2F //char c; //while (scanf_s("%c", &c, 1) != EOF) //{ // int C = c; // if (C >= 'a' && C <= 'z' || C >= 'A' && C <= 'Z') // { // printf("%c", 25 - (C - 97) + 97 - 32); // } // else printf("%c", C); //} //return 0; //C2G //int n; //scanf_s("%d", &n); //int hh, mm, ss; //int hh1, mm1, ss1; //int hh2, mm2, ss2; //int t1,t2; //scanf_s("%d:%d:%d", &hh, &mm, &ss); //int t = 3600 * hh + 60 * mm + ss; //for (int i = 0; i < n; i++) //{ // scanf_s("%d:%d:%d", &hh1, &mm1, &ss1); // scanf_s("%d:%d:%d", &hh2, &mm2, &ss2); // t1 = 3600 * hh1 + 60 * mm1 + ss1; // t2 = 3600 * hh2 + 60 * mm2 + ss2; // int tt = t2 - t1; // printf("%02d:%02d:%02d ",tt/3600, (tt % 3600) / 60,tt%60); // if (t2 - t1 < t) // { // printf("No~555~\n"); // } // else printf("Yes!\n"); //} //C2H //long long h, p, q; //while (scanf_s("%lld%lld%lld", &h, &p, &q) != EOF) //{ // long long n; // scanf_s("lld", &n); // long long sum = 0; // long long flag = 0; // for (int i = 0; i < n; i++) // { // long long a; // sum = sum + a; // if (h + sum <= p && flag == 0) // { // flag = 1; // printf("down\n"); // } // if (h + sum >= q && flag == 0) // { // flag = 1; // printf("up\n"); // } // } // if (flag == 0) // { // if (sum > 0) // { // printf("up\n"); // } // else if (sum < 0) // { // printf("down\n"); // } // else // printf("No\n"); // } //} //return 0; //C2I' //int n, a; //scanf_s("%d", &n); //int arr[1000]; //int j = 0; //int sum = 0; //for (int i = 0; i < n; i++) //{ // scanf_s("%d", &a); // arr[i] = a; //} //for (j = 0; j < n; j++) //{ // sum = 0; // for (int k = 0; k < n; k++) // { // if (arr[k] == j + 1) // { // for (int l = 0; l < k; l++) // { // if (arr[l] > j + 1) // { // sum = sum + 1; // } // } // } // } // printf("%d ", sum); //}return 0; //C2I //int nums[10010]; //int perm[10010]; //int n; //scanf_s("%d", &n); //for (int i = 1; i <= n; i++) //{ // scanf_s("%d", &nums[i]); //} //for (int i = 1; i <= n; i++) //{ // int gap = 0, index = 0; // while (gap <= nums[i]) // { // index++; // if (perm[index] == 0) // { // gap++; // } // } // perm[index] = i; //} //for (int i = 1; i <= n; i++) //{ // printf("%d", perm[i]); //} //return 0; //E2A //printf("In C language, if you want to print '%%', use printf(\"%%%%\");\n"); //printf("To print a double quote like \"this\", write printf(\"\\\"this\\\"\"); \n"); //printf("And if you want to show a path like C:\\Program, write printf(\"C:\\\\Program\");"); //return 0; //E2B //char a; //int i = 0; //while ((a = getchar()) != '\n' && a != EOF) //{ // if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u' || a == 'A' || a == 'E' || a == 'I' || a == 'O' || a == 'U') // { // i++; // } //} //printf("%d", i); //return 0; //E2C //int n;//灯笼数量 //int m;//按钮次数 //int a;//开关状态 //int arr[1000];//存储开关 //int Arr[1000];//存储状态 //scanf_s("%d%d", &n, &m); //for (int i = 0; i < m; i++) //{ // scanf_s("%d", &a); // arr[i] = a; //} //for (int j = 0; j <= n; j++) //{ // Arr[j] = 0; //} //for (int k = 0; k < n; k++) //{ // int sum = 0; // if (k == 0) // { // for (int s = 0; s < m; s++) // { // if (arr[s]== 1 || arr[s] == 2 || arr[s] == n) // { // sum++; // } // } // Arr[0] = sum % 2; // } // else if (k == n - 1) // { // for (int s = 0; s < m; s++) // { // if (arr[s] == n || arr[s] == n - 1 || arr[s] == 1) // { // sum++; // } // } // Arr[n-1] = sum % 2; // } // else // { // for (int s = 0; s < m; s++) // { // if (arr[s] == k || arr[s] == k + 1 || arr[s] == k + 2) // { // sum++; // } // } // Arr[k] = sum % 2; // } //} //for (int t = 0; t < n; t++) //{ // printf("%d ", Arr[t]); //} //return 0; //E2D //int flag = 0; //char a; //int arr[100010]; //int i=0; //while ((a = getchar()) != '\n' && a != EOF) //{ // arr[i] = a; // i++; //} //for (int j = 0; j <= i; j++) //{ // if (j >= 1) // { // if (arr[j] == 'r' && (arr[j - 1] == 'a' || arr[j - 1] == 'e' || arr[j - 1] == 'i' || arr[j - 1] == 'o' || arr[j - 1] == 'u')) // { // arr[j] = ' '; // } // } //} //for (int k = 0; k < i; k++) //{ // if (arr[k] != ' ') // { // printf("%c", arr[k]); // } //} //return 0; //E2E //int n, k, a, b; //int arrn[1000]; //int arrk[1000]; //scanf_s("%d%d", &n, &k); //for (int i = 0; i < n; i++) //{ // scanf_s("%d", &a); // arrn[i] = a; //} //for (int j = 0; j < k; j++) //{ // scanf_s("%d", &b); // arrk[j] = b; // for (int i = 0; i < n; i++) // { // if (arrk[j] == i + 1) // { // arrn[i] = 0; // } // } //} //for (int i = 0; i < n; i++) //{ // printf("%d ", arrn[i]); //} //return 0; //E2F? //int n;//车站数量 //int d;//两站距离 //int D=0; //scanf_s("%d", &n); //int darr[100010]; //for (int i = 0; i < n-1 ; i++) //{ // scanf_s("%d", &d); // darr[i] = d; //} //int q;//询问次数 //int s, t; //scanf_s("%d", &q); //for (int j = 0; j < q; j++) //{ // D = 0; // scanf_s("%d%d", &s, &t); // for (int j = s; j < t; j++) // { // D = D + darr[j - 1]; // } // printf("%d", D + (t - s) * 190); //} //return 0; //E2F //int n; //scanf_s("%d", &n); //long long arr[100010] = { 0 }; //for (int i = 1; i <= n - 1; i++) //{ // int d; // scanf_s("%d", &d); // arr[i] = arr[i - 1] + d; //} //int q; //scanf_s("%d", &q); //while (q--) //{ // int s, t; // scanf_s("%d %d", &s, &t); // long long D = arr[t - 1] - arr[s - 1]; // long long DD = D + (t - s) * 190; // printf("%lld\n", DD); //} //return 0; //E2G //double a, b, c; //scanf_s("%lf%lf%lf", &a, &b, &c); //if (a == 0 && b == 0 && c==0) //{ // printf("Infroots"); //} //else if (a == 0 && b != 0) //{ // printf("Just one root: %.2lf", -c / b); //} //else if (a != 0) //{ // int delta = b * b - 4 * a * c; // if (delta == 0) // { // printf("The same two roots: %.2lf", -b / (2 * a)); // } // else if (delta < 0) // { // printf("No Root"); // } // else // { // double x1 = (-b + sqrt(delta)) / (2 * a); // double x2 = (-b - sqrt(delta)) / (2 * a); // if (x1 >= x2) // { // printf("%.2lf %.2lf", x1, x2); // } // if (x1 < x2) // { // printf("%.2lf %.2lf", x2, x1); // } // } //} //else //{ // printf("No Root"); //} //return 0; //E2H? //int n; //scanf_s("%d", &n); //int p; //int arrp[200010]; //int Sum = 0; //for (int i = 0; i < n; i++) //{ // scanf_s("%d", &p); // arrp[i] = p; // Sum = Sum + p; //} //int m; //int k; //scanf_s("%d", &m); //for (int i = 0; i < m; i++) //{ // scanf_s("%d", &k); // if (Sum < k) // { // printf("No Way!"); // } // int sum = 0; // for (int t = 0; t < n; t++) // { // sum = sum + arrp[n - 1 - t]; // if (sum == k) // { // printf("%d", n - t); // break; // } // } //} //return 0; //E2H! //int n; //定义总天数 10 //scanf_s("%d", &n); //输入总天数 //int total = 0; //定义数组和 //int temp; //暂存输入的数组 //for (int i = 0; i < n; i++) //循环n次输入数组 //{ // scanf_s("%d", &temp); //输入数组值 // arrp[i] = temp; //赋值数组 // total = total + arrp[i]; //计算数组数据和 //} //0 0 1 1 0 1 0 1 1 0 //int sum = 0; //初始化定义有限数组位和 //for (int i = n - 1; i >= 0; i--)//循环从反读取数组每一位 i=9 i=8 i=7 i=6 i=5 //{ // sum = sum + arrp[i]; //从后加和数组每一位数据 sum=0+arrp[9]=0 sum=0+arrp[8]=1 sum=1+arrp[7]=2 sum=2+arrp[6]=2 sum=2+arrp[5]=3 // if (!found[sum]) //如果该数位违背读取 // { // found[sum] = true; //将未读取状态改为读取 found[0]=true found[1]=true found[2]=true found[2]不执行 found[3]=true // fd[sum] = i + 1; //将对应天数赋值 fd[0]=10 fd[1]=9 fd[2]=8 fd[3]=6 // } //} //int m, k; //定义输出组数及输入数据 //scanf_s("%d", &m); //输入组数 //for (int i = 0; i < m; i++) //执行组数次循环 //{ // scanf_s("%d", &k); //输入需要的次数 // if (k > total || k <= 0) //次数超过总数或次数低于0 // { // printf("No Way!\n"); //反馈 // } // else if (found[k]) //有效范围内,有true即输出对应的fd // { // printf("%d\n", fd[k]); //输出fd // } // else // { // printf("No Way!\n"); // } //} //return 0; //E2I //int n;//数组n个数 //int q;//而后有q行 //scanf_s("%d", &n); //scanf_s("%d", &q); //int arr[2000];//第二行的数组 //for (int i = 1; i <= n; i++)//1开始 //{ // scanf_s("%d", &arr[i]);//数组赋值 //} //int op;//操作种类 //int x, y;//操作参数 //int sum6 = 0; //for (int i = 1; i <= q; i++) //{ // sum6 = 0; // scanf_s("%d %d %d", &op, &x, &y); // if (op == 1) // { // arr[x] = arr[y]; // } // if (op == 2) // { // int temp = arr[y]; // arr[y] = arr[x]; // arr[x] = temp; // } // if (op == 3) // { // arr[x] = arr[x] + y; // } // if (op == 4) // { // arr[x] = y; // } // if (op == 5) // { // printf("%d\n", arr[x] - arr[y]); // } // if (op == 6) // { // for (int i = x; i <= y; i++) // { // sum6 = sum6 + arr[i]; // } // printf("%d\n", sum6); // } //} //return 0; //E2J //int n;//数列长度 //scanf_s("%d", &n); //输入3与输入1等价; //long long a3 = 10; //long long a4 = 16; //long long a5 = 26; //int i; //if (n == 3) //{ // printf("%lld", a3); //} //else if (n == 4) //{ // printf("%lld", a4); //} //else if (n == 5) //{ // printf("%lld", a5); //} //else //{ // for (i = 5; i < n; i++) // { // a3 = a4; // a4 = a5; // a5 = (a3 + a4) % 998244353; // } // printf("%lld", a5); //} //return 0; scanf_s("%d", &n); int i = 1; z1[1] = 0; for (i=1; i < n; i = i + 1) { scanf_s("%d", &d[i]); z1[i + 1] = d[i] + z1[i]; } int m; i = 1; scanf_s("%d", &m); for (; i <= m; i = i + 1) { scanf_s("%d%d", &a[i], &e[i]); } i = 1; for (; i < m; i = i + 1) { printf("%d\n", z1[e[i]] - z1[a[i]] + (e[i] - a[i]) * 190); } printf("%d", z1[e[i]] - z1[a[i]] + (e[i] - a[i]) * 190); return 0; }为什么是WA
最新发布
09-27
题目 `Codeforces 2128F Strict Triangle` 是一道较为复杂的计算几何与构造题。题目要求构造一个满足特定条件的三角形,并根据给定的点集判断是否存在这样的三角形。下面将从题目解析、解题思路和代码实现三个方面进行说明。 ### 题目大意 给定平面上 $n$ 个点,要求判断是否存在三个点 $A, B, C$,使得: 1. 三角形 $ABC$ 是非退化的(即面积不为零); 2. 满足 $\angle ABC$ 是严格锐角(即小于 $90^\circ$)。 如果存在这样的三角形,输出任意一组满足条件的三点;否则,输出 `NO`。 ### 解题思路 #### 1. 几何性质分析 判断一个角是否为锐角,可以通过向量内积的方式进行判断。设三点 $A, B, C$ 构成三角形,其中 $B$ 为角的顶点,则: $$ \vec{BA} \cdot \vec{BC} = |\vec{BA}| \cdot |\vec{BC}| \cdot \cos(\theta) $$ 若 $\theta < 90^\circ$,则 $\cos(\theta) > 0$,因此只需要判断 $\vec{BA} \cdot \vec{BC} > 0$。 #### 2. 算法选择 - 枚举所有点对 $B$ 作为角的顶点; - 对于每个点 $B$,枚举所有点 $A, C$,并计算 $\vec{BA} \cdot \vec{BC} > 0$; - 同时确保三点不共线(即三角形面积不为零)。 #### 3. 时间复杂度优化 由于 $n$ 最大为 $1000$,直接三重循环会导致 $O(n^3)$ 的时间复杂度,这在最坏情况下会超时。因此需要优化: - 固定点 $B$,枚举所有其他点作为 $A$; - 对于每个 $A$,再枚举所有点 $C$,但跳过 $A=C$ 或 $B=C$ 的情况; - 利用向量点积的性质快速判断。 这样复杂度为 $O(n^2)$,对于 $n=1000$ 可以接受。 ### 代码实现 以下是一个完整的 AC 代码实现,用于判断是否存在满足条件的三角形并输出结果: ```cpp #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1005; struct Point { ll x, y; } points[MAXN]; ll dot(Point a, Point b, Point c, Point d) { ll dx1 = b.x - a.x; ll dy1 = b.y - a.y; ll dx2 = d.x - c.x; ll dy2 = d.y - c.y; return dx1 * dx2 + dy1 * dy2; } ll cross(Point a, Point b, Point c, Point d) { ll dx1 = b.x - a.x; ll dy1 = b.y - a.y; ll dx2 = d.x - c.x; ll dy2 = d.y - c.y; return dx1 * dy2 - dx2 * dy1; } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { cin >> points[i].x >> points[i].y; } for (int b = 0; b < n; ++b) { for (int a = 0; a < n; ++a) { if (a == b) continue; for (int c = a + 1; c < n; ++c) { if (c == b) continue; // Check angle at b ll dot_product = dot(points[b], points[a], points[b], points[c]); if (dot_product > 0) { ll area = cross(points[a], points[b], points[b], points[c]); if (area != 0) { cout << "YES" << endl; cout << a + 1 << " " << b + 1 << " " << c + 1 << endl; return 0; } } } } } cout << "NO" << endl; return 0; } ``` ### 说明 - `dot()` 函数用于计算两个向量的点积; - `cross()` 函数用于计算两个向量的叉积,判断是否共线; - 枚举所有可能的点 $B$,并遍历其他点 $A, C$,判断是否满足锐角条件; - 若找到符合条件的三角形,立即输出并终止程序。 ### 时间与空间复杂度 - 时间复杂度:$O(n^2)$; - 空间复杂度:$O(n)$,仅存储点集。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值