USACO 之 Section 1.3 Greedy Algorithm

来源:互联网 发布:艾森豪威尔总统 知乎 编辑:程序博客网 时间:2024/05/18 01:47

Mixing Milk单价越少,买相同数量的牛奶花费越少。。。先排序,再求解。。。

/*ID: JmingPROG: milkLANG: C++*/#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;int N, M;struct myNode {    int P, A;} node[5005];bool Cmp(const myNode &n1, const myNode &n2){    if (n1.A == n2.A) return n1.P < n2.P;    else return n1.A < n2.A;}void Solve() {    int myCost = 0;    int myCount = 0;    for (int i = 0; i < M; ++i) {        if (myCount + node[i].P > N) {            myCost += (N-myCount)*node[i].A;            break;        }else {            myCount += node[i].P;            myCost += node[i].A*node[i].P;        }    }    printf("%d\n", myCost);}int main(){freopen("milk.in", "r", stdin);freopen("milk.out", "w", stdout);scanf("%d %d", &N, &M);for (int i = 0; i < M; ++i) {        scanf("%d %d", &node[i].A, &node[i].P);}sort(node, node + M, Cmp);Solve();return 0;}

Barn Repair: 

注意:牛所在的牛棚的编号是乱序的,需要先从小到大排序
分情况讨论:
1)M == 1 : 最大的牛棚编号 - 最小的牛棚编号 + 1
2)M >= C :  直接输出 C 即可
3)M < C   :  根据各牛棚编号之间的差值,贪心处理(尽量删去差值大的,选取差值小的

/*ID: JmingPROG: barn1LANG: C++*/#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>#include <algorithm>#include <functional>#include <string>#include <cstring>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;#define eps 1e-8#define MAX_C 205int M, S, C;int myArr[MAX_C];vector<int> myVec;struct myNode {int Pos;int Dis;};myNode node[MAX_C];bool Cmp(const myNode n1, const myNode n2) {return n1.Dis > n2.Dis;}void Solve() {int myBegin = 0;int Sum = 0, tmp;myVec.push_back(C-1);for (int i = 0; i < myVec.size(); ++i) {tmp = myArr[myVec[i]] - myArr[myBegin] + 1;if (tmp) Sum += tmp;else ++Sum;myBegin = myVec[i] + 1;}printf("%d\n", Sum);}int main() {freopen("barn1.in", "r", stdin);freopen("barn1.out", "w", stdout);scanf("%d %d %d", &M, &S, &C);for (int i = 0; i < C; ++i) {scanf("%d", &myArr[i]);}sort(myArr, myArr + C);for (int i = 1; i < C; ++i) {node[i - 1].Pos = i - 1;node[i - 1].Dis = myArr[i] - myArr[i - 1];}if(M >= C) {        printf("%d\n", C);        return 0;}if (1 == M) {        printf("%d\n", myArr[C - 1] - myArr[0] + 1);        return 0;}sort(node, node + (C - 1), Cmp);for (int i = 0; i < (M - 1); ++i) {myVec.push_back(node[i].Pos);}sort(myVec.begin(), myVec.end());Solve();myVec.clear();return 0;}

Prime Cryptarithm: 穷举即可。。。

/*ID: JmingPROG: crypt1LANG: C++*/#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>#include <algorithm>#include <functional>#include <string>#include <cstring>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;#define eps 1e-8int myArr[15];int N;bool myJudge(int x) {while (x) {int tmp1 = x % 10;int i;for (i = 0; i < N; ++i) {if (tmp1 == myArr[i]) {break;}}if (i == N) {return false;}x /= 10;}return true;}void Solve() {int ans = 0;for (int i = 0; i < N; ++i) {for (int j = 0; j < N; ++j) {for (int k = 0; k < N; ++k) {int mydata = myArr[i] * 100 + myArr[j] * 10 + myArr[k];for (int m = 0; m < N; ++m) {int data1 = mydata * myArr[m];if (!myJudge(data1)) continue;if (data1 >= 1000) continue;for (int n = 0; n < N; ++n) {int data2 = mydata * myArr[n];if (!myJudge(data2)) continue;if (data2 >= 1000) continue;int myMul = data1 + data2 * 10;if (!myJudge(myMul)) continue;if (myMul >= 10000) continue;++ans;}}}}}printf("%d\n", ans);}int main(){freopen("crypt1.in", "r", stdin);freopen("crypt1.out", "w", stdout);scanf("%d", &N);for (int i = 0; i < N; ++i) {scanf("%d", &myArr[i]);}Solve();return 0;}

Combination Lock:
思路:
(1)根据 N 可以求出:
         1)农夫约翰的号码组合所能产生的不同的开锁号码组合的数目 S1;
         2)预设号码组合所能产生的不同的开锁号码组合的数目 S2。
(2)再求出以上1)和2)相同的号码个数 S3。
(3)推出答案: S1 + S2 - S3

注意: 锁上标号为 N 的号码在程序中用 0 表示

/*ID: JmingPROG: comboLANG: C++*/#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>#include <algorithm>#include <functional>#include <string>#include <cstring>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;#define eps 1e-8int N, Sum;vector<int> arr0[3], arr1[3];int Ini(vector<int> arr[3]) {int cnt = 1;int tmp;for (int i = 0; i < 3; ++i) {scanf("%d", &tmp);int pos = 0;for (int j = -2; j <= 2; ++j) {int mytmp = (tmp + j + N) % N;   if (find(arr[i].begin(), arr[i].end(), mytmp) == arr[i].end()) {arr[i].push_back(mytmp);}}cnt *= arr[i].size();}return cnt;}void Solve() {int mycount = 1;for (int i = 0; i < 3; ++i) {int tmp = 0;for (int j = 0; j < arr0[i].size(); ++j) {if (find(arr1[i].begin(), arr1[i].end(), arr0[i][j]) != arr1[i].end()) {++tmp;}}mycount *= tmp;}printf("%d\n", Sum - mycount);}int main(){freopen("combo.in", "r", stdin);freopen("combo.out", "w", stdout);scanf("%d", &N); Sum = 0;Sum += Ini(arr0);Sum += Ini(arr1);Solve();return 0;}


0 0
原创粉丝点击