【算法笔记】【几何初步、数学初步、矩阵计算】ICPC训练联盟2021寒假冬令营(3)笔记
題目鏈接
A題題解:枚舉法+簡單直線方程知識。
本題采取枚舉方法,在[-500, 500]的范圍內枚舉A和B,將櫻桃坐標代入直線方程Ax+By,如果Ax+By大于0,則櫻桃在直線方;小于0,則櫻桃在直線下方;等于0,則不允許,因為櫻桃不能在直線上。枚舉直至產生第一個解。
#include <iostream> #include<algorithm> using namespace std; int a, b; int charry[101][2]; float pos(int a, int b, int x, int y) {return a * x + b * y; } int main() {int n;while (cin >> n && n != 0) {bool flag = false;for (int i = 0; i < 2 * n; i++) {cin >> charry[i][0] >> charry[i][1];}for (int ai = -500; ai <= 500; ai++) {for (int bi = -500; bi <= 500; bi++) {int top = 0, end = 0;for (int i = 0; i < 2 * n; i++) {if (charry[i][0] >= -100 && charry[i][0] <= 100 || charry[i][1] >= -100 && charry[i][1] <= 100){int ans = pos(ai, bi, charry[i][0], charry[i][1]);if (ans > 0)top++;else if (ans < 0)end++;else if (ans == 0)break;}}if (top == end && top + end == 2 * n && !flag){cout << ai << " " << bi << endl;flag = true;}}if (flag)break;}}return 0; }B題題解:應用幾何知識進行求解(動手畫一畫)
C題:差值枚舉+GCD
?如果兩個不同的數除以一個除數的余數相同,則這兩個不同數的差值一定是除數的倍數。
利用差值枚舉除數即可。
?所以,本題的算法如下:先求出原序列的一階差分序列,然后求出所有非零元素的GCD。
知識點:歐幾里得算法就是求整數a和b的最大公約數。(是遞歸算法~)
C題參考代碼:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 1007 int num[N]; int gcd(int a, int b) {if (b == 0)return a;elsereturn(gcd(b, a % b)); } int main() {int x;bool flag = false;while (1) {memset(num, 0, sizeof(num));scanf("%d", &x);//第一個數,為0跳出if (x == 0)break;int len = 0;num[len++] = x;while (x != 0) {scanf("%d", &x);num[len++] = x;}len--;int ans = num[0] - num[1];for (int i = 1; i < len - 1; i++) {num[i] = num[i] - num[i + 1];ans = gcd(num[i] == 0 ? ans : num[i], ans);}if (ans < 0)ans = -ans;cout << ans << endl;}return 0; }D題:擴展歐幾里得裸題
知識點:歐幾里得算法
//擴展歐幾里得算法 int exgcd(int a, int b, int& x, int& y) {if (b == 0) { x = 1; y=0; return a; }int t = exgcd(b, a % b, x, y); int x0 = x, y0 = y;x = y0;y = x0 - (a / b) * y0;return t; }D題參考代碼:
#include <iostream> using namespace std; int exgcd(int a, int b, int& x, int& y) {if (b == 0) { x = 1; y=0; return a; }int t = exgcd(b, a % b, x, y); int x0 = x, y0 = y;x = y0;y = x0 - (a / b) * y0;return t; } int main(){int a, b, d, x, y;while (scanf("%d%d", &a, &b) != EOF) {d = exgcd(a, b, x,y); printf("%d %d %d\n", x, y, d);}return 0; }E題:題型為由局部解推出整體解
此類題型沒有固定的算法,需根據題目自己得出,且僅限于此題。(此題型《算法設計編程實驗》第一章中有做整體講解)
參考代碼:暫時沒時間寫了。。。參考錄屏
F題:概率論基礎知識
知識點:概率論初步隨機現象是指這樣的客觀現象,當人們觀察它時,所得的結果不 能預先確定,而只是多種可能結果中的一種。在自然界和人類社會中,存在著大量的隨機現象。擲硬幣就是最常見的隨機現象,可能出現硬幣的正面,也可能出現硬幣的反面。概率論是研究隨 機現象數量規律的數學分支。
題解:
G題:嗯。。。概率+幾何?
總之題解:
參考代碼:
H題:求個導就行
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 100007 int numa[N]; int main() {int x;while (scanf("%d", &x) != EOF) {getchar();int len = 0;char ch;while (1) {scanf("%d", &numa[len++]);ch = getchar();if (ch == '\n')break;}int ans = numa[len - 2];for (int i = 2; i <= len - 1; i++) {ans += numa[len - i] * i * x;x *= x;}cout << ans << endl;}return 0; }更新 矩陣計算
4.C UVA11349 Symmetric Matrix
#include <iostream> #include<string> #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; #define N 107 int T; long long arr[N][N]; int main() {cin >> T;for (int t = 1; t <= T; t++) {int n;getchar();getchar();getchar();getchar();getchar();cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {cin >> arr[i][j];}}bool flag = true;for (int i = 0; i < n; i++) {for (int j = 0; j <n; j++) {if (arr[i][j] < 0 || arr[i][j] != arr[n - 1 - i][n - 1 - j]) {flag = false;break;}}if (!flag)break;}cout << "Test #" << t;if (flag)cout << ":Symmetric." << endl;elsecout << ":Non-symmetric." << endl;}return 0; }4.D POJ 2941 Homogeneous Squares
也是一個局部解推全局解的題。即,自己造算法
//超時原因居然是因為用的cin。。。。
4.E
明天再做 遞增序列
4.F POJ1050 To the Max
#include <iostream> #include<string> #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; #define N 107 #define INF 0X3f3f3f3f int maxArry(int a[], int n) {int m = -INF;int tmp = -1;for (int i = 0; i < n; i++) {if (tmp > 0)//每個循環里的tmp都是包括i處的最大子序列 tmp += a[i];//如果是有利的(即對包括i處構成最大子序列和有利),就加上 elsetmp = a[i];//不利的話就舍去,從新記起if (tmp > m)m = tmp;//記錄最大值 }return m; } int main() {int a[N][N];int n;cin >> n;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {cin >> a[i][j];}}int ans = -INF;for (int i = 0; i < n; i++) {int s[N] = { 0 };for (int j = i; j < n; j++) {for (int k = 0; k < n; k++) {s[k] += a[j][k];}int anss = maxArry(s, n);if (anss > ans)ans = anss;}}cout << ans;return 0; }G往后就放排序里啦~
總結
以上是生活随笔為你收集整理的【算法笔记】【几何初步、数学初步、矩阵计算】ICPC训练联盟2021寒假冬令营(3)笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样回答面试题更好?以及注意事项
- 下一篇: 简单实现Android图片三级缓存机制