2013杭電多校第五場
阿新 • • 發佈:2019-01-29
1006 Magic Pen 6
題目的意思就是給你一串數字,讓你找出其中最長的一個串使得這些數字之和模M等於0:
那就直接先計算出sum(i) = a1+a2+....+ai;一串數字的和就是這串數字的首數字和末尾數字的sum之差,要使得字串
最長,那麼就使用兩個指標,一個從頭開始,一個從尾部開始,只要找到滿足條件的數字串就直接跳出,這時候的長度
肯定就是最長的了:
#include <iostream> #include <cstdio> #include <string> #include <string.h> #include <map> #include <vector> #include <cstdlib> #include <algorithm> #include <cmath> #include <queue> #include <set> #include <stack> #include <functional> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cassert> #include <bitset> #include <stack> #include <ctime> #include <list> #define INF 0x7fffffff #define max3(a,b,c) (max(a,b)>c?max(a,b):c) #define min3(a,b,c) (min(a,b)<c?min(a,b):c) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; #define N 100005 int a[N] ; __int64 sum[N] ; int main() { int n , m ; while(cin >> n >> m) { mem(sum ,0) ; for (int i = 1 ; i <= n ; i ++ ) { scanf("%d",&a[i]) ; sum[i] = sum[i - 1] + a[i] ; } __int64 l = 1 , r = n ; __int64 ed ; __int64 ans = 0 ; __int64 c = sum[n] % m ; if(sum[n] % m == 0) { cout << n << endl; continue ; } int flag = 0 ; for (int ed = n ; ed >= 1 ; --ed ) { for (int st = 1 ; st + ed - 1 <= n ; ++st) { if((sum[st + ed - 1] - sum[st - 1]) % m == 0) { cout << ed << endl; flag = 1 ; break ; } } if(flag) break ; } if(!flag) cout << 0 << endl; } return 0 ; }
1005 Another Graph Game
這道題目一開始想複雜了,想到了刪邊遊戲,太複雜了。既然就是求差,那麼可以分情況討論一下:
若沒有邊權,則對點權從大到小排序即可。
考慮邊,將邊權拆成兩半加到它所關聯的兩個點的點權中即可。因為當兩個人分別選擇不同的點時,這一權值將互相抵消。
1009 Partition#include <iostream> #include <cstdio> #include <string> #include <string.h> #include <map> #include <vector> #include <cstdlib> #include <algorithm> #include <cmath> #include <queue> #include <set> #include <stack> #include <functional> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cassert> #include <bitset> #include <stack> #include <ctime> #include <list> #define INF 0x7fffffff #define max3(a,b,c) (max(a,b)>c?max(a,b):c) #define min3(a,b,c) (min(a,b)<c?min(a,b):c) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; #define N 100001 int n, m; double num[N]; int a, b; double w; bool cpp(double a, double b) { return a > b; } double ans = 0; int main() { while(scanf("%d%d", &n, &m) == 2) { mem(num, 0); ans = 0; for(int i = 0; i < n; ++i) scanf("%lf", &num[i]); for(int i = 0; i < m; ++i) { scanf("%d%d%lf", &a, &b, &w); num[a-1] += w/2.0; num[b-1] += w/2.0; } sort(num, num + n, cpp); double la = 0, lb = 0; for(int i = 0; i < n ; i = i + 2) { ans += num[i] - num[i+1]; } printf("%.0lf\n",ans); } return 0; }
數論? 真的不會
題目大意:將一個數n拆分成幾個數相加,問有多少種方案?
思路:
#include <iostream> #include <cstdio> #include <string> #include <string.h> #include <map> #include <vector> #include <cstdlib> #include <algorithm> #include <cmath> #include <queue> #include <set> #include <stack> #include <functional> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cassert> #include <bitset> #include <stack> #include <ctime> #include <list> #define INF 0x7fffffff #define max3(a,b,c) (max(a,b)>c?max(a,b):c) #define min3(a,b,c) (min(a,b)<c?min(a,b):c) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int mod = 1e9+7; #define N 100020 int p[N]; void Partition() { p[0] =1; for(int n = 1; n <= 1e5; ++n) { int fac = 1; int k =1; while(1) { int t = n - k * (3 * k - 1) / 2; if(t < 0) break; p[n] = (p[n] + fac * p[t])%mod; if(t-k >= 0) p[n] = (p[n] + fac*p[t-k])%mod; p[n] %= mod; fac = -fac; ++k; } p[n] = (p[n] + mod) % mod; } } int main() { Partition(); int d; scanf("%d",&d); while(d--) { int c; scanf("%d",&c); printf("%d\n",p[c]); } return 0; }