【2012天津区域赛】部分题解 hdu4431—4441
1001:
題意:
給你13張麻將牌,問可以胡哪些張
思路:
枚舉可能接到的牌,然后dfs判斷能否胡
?
1002:
題意:
已知n,m?求?n的所有約數在m進制下的平方和
做法:
隊長用java高精度寫的
代碼:
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.PrintWriter; import java.io.ObjectInputStream.GetField; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Scanner;public class Main {static BigInteger getSum(int i, int base){BigInteger ans= BigInteger.ZERO;BigInteger divider = BigInteger.valueOf(i);String s = divider.toString(base);for (int j = 0; j < s.length(); j++) {BigInteger k = new BigInteger(s.substring(j, j + 1),base);ans = k.multiply(k).add(ans);}return ans;}public static void main(String[] args) {Scanner cin = new Scanner(new BufferedInputStream(System.in));PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out));while (cin.hasNext()) {int n = cin.nextInt();int base = cin.nextInt();BigInteger ans = BigInteger.ZERO;for (int i = 1; i * i <= n; i++){if (n % i == 0) {// i是dividerans = ans.add(getSum(i, base));if(i*i!=n)ans = ans.add(getSum(n/i, base));}}cout.println(ans.toString(base).toUpperCase());}cin.close();cout.close();}}View Code
?
1003:
題意:
給定一串數,每次有三種操作:
1.把當前數加/減1
2.當前數和后面一個數加/減1
3.當前數和后面兩個數加/減1
(加減完后的結果是在0~9循環的)
求把當前狀態變到目標狀態需要的最小操作數
做法:
處理到每個數的時候最多對后面兩個數產生影響,因此十進制最多有 10^2=100?種情況,可以全部存下
可以進行dp,dp[i][j]表示前i個數已經達到目標狀態?,第i+1個數和第i+2個數的被操作情況為j(狀壓一下)的最小操作數,轉移只需要枚舉三種操作的次數即可
代碼:
#include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> using namespace std; #define inf 100000 int mod(int x) {if(x>=0)return x%10;elsereturn (10+x%10)%10; } char s[1010]; char to[1010]; int dp[1010][1010]; int num[3]; int tmp[3]; int p[3]= {1,20,400}; int main() {while(scanf("%s%s",s+1,to+1)!=EOF){memset(dp,0x3f,sizeof(dp));dp[0][210]=0;int n=strlen(s+1);for(int i=1; i<=n; i++){for(int j=1; j<400; j++){if(dp[i-1][j]>=inf)continue;for(int k=0; k<2; k++){num[k]=(j%p[k+1])/p[k];}int cha=mod(to[i]-s[i]-(num[0]-10));for(int a=0; a<=cha; a++){for(int b=0; a+b<=cha; b++){int c=cha-a-b;tmp[0]=num[1]-10+b+c;tmp[0]=tmp[0]%10+10;tmp[1]=c+10;dp[i][tmp[0]+tmp[1]*20]=min(dp[i][tmp[0]+tmp[1]*20],dp[i-1][j]+cha);}}cha=10-cha;for(int a=0; a<=cha; a++){for(int b=0; a+b<=cha; b++){int c=cha-a-b;tmp[0]=10-(20-num[1]+b+c)%10;tmp[1]=10-c;dp[i][tmp[0]+tmp[1]*20]=min(dp[i][tmp[0]+tmp[1]*20],dp[i-1][j]+cha);}}}}//printf("%d\n",dp[1][9+9*20]);//printf("%d\n",dp[2][9+10*20]);printf("%d\n",dp[n][210]);}return 0; }View Code
?
1005:
題意:
一個圖有n個點,初始在點1,每次加滿油后最多能跑d距離,現在點1有一個加油站,問環游全程回到1需要怎么建加油站
第i點建加油站的話?二進制第i位為1,答案要滿足建造情況的二進制數最小
做法:
貪心,要盡量要高位的點不建,先假設所有點建了,再從大到小考慮,如果當前點不建也能滿足需求,則把該點加油站刪去
因為要考慮連通性所以判斷是否滿足需求要用bfs
代碼:
#include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> #include<queue> #include<math.h> using namespace std; int g[150][150]; int x[150]; int y[150]; int vi[150]; int vis[150]; int n,d; queue<int>q; int check() {memset(vis,0,sizeof(vis));while(!q.empty())q.pop();q.push(0);while(!q.empty()){int now=q.front();vis[now]=1;q.pop();for(int i=0;i<n;i++){if(!vis[i]){if(g[now][i]<=d/2){vis[i]=1;}if(g[now][i]<=d&&vi[i]){q.push(i);}}}}for(int i=0;i<n;i++){if(vis[i]==0)return 0;}return 1; } int main() {//freopen("in.txt","r",stdin);while(scanf("%d%d",&n,&d)!=EOF){for(int i=0;i<n;i++){vi[i]=1;}for(int i=0; i<n; i++){scanf("%d%d",x+i,y+i);}for(int i=0; i<n; i++){for(int j=0; j<n; j++){g[i][j]=ceil(sqrt((double)((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))));}}if(check()==0){puts("-1");continue;}for(int i=n-1; i>=1; i--){vi[i]=0;if(!check())vi[i]=1;}int f=1;for(int i=n-1; i>=0; i--){if(vi[i]){printf("1");f=0;}else{if(f==0)printf("0");}}puts("");}return 0; }View Code
?
1006:
?題意: n個字符串,對于每一個子串可以表示為一個數字, 求所有子串的數字和相加對2012取模,, 相同數字只算一次。
?
這題可以先把n個字符串用一個沒有出現過的字符隔開連起來。然后求sa, lcp。
我們可以先看一個簡單的例子。
s = 12345
num[1] = 1 ? ? ? ? ? ? sum[1] = 1
num[2] = 12 ? ? ? ? ? sum[2] = 1 + 12
num[3] = 123 ? ? ? ? sum[3] = 1 + 12 + 123
num[4] = 1234 ? ? ? sum[4] = 1 + 12 + 123 + 1234?
num[5] = 12345 ? ? sum[5] = 1 + 12 + 123 + 1234 + 12345
如果求[3, 4] ?, 只需要 sum[5] - sum[2] - num[2] * (10 + 100 + 1000);
判重時 只要從 i+ lcp[rank[i]] ?開始算就可以了,,因為公共前綴那一部分 在前面已經算了。
上代碼。。
1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 typedef unsigned long long ull; 16 typedef long long ll; 17 const int inf = 0x3f3f3f3f; 18 const double eps = 1e-8; 19 const int mod = 2012; 20 const int maxn = 2e5+100; 21 int sum [maxn], num[maxn]; 22 string s; 23 int sa[maxn], Rank[maxn], tmp[maxn], lcp[maxn]; 24 int k, len; 25 bool cmp(int i, int j) 26 { 27 if (Rank[i] != Rank[j]) 28 return Rank[i] < Rank[j]; 29 else 30 { 31 int x = (i+k <= len ? Rank[i+k] : -1); 32 int y = (j+k <= len ? Rank[j+k] : -1); 33 return x < y; 34 } 35 } 36 void build_sa() 37 { 38 for (int i = 0; i <= len; i++) 39 { 40 sa[i] = i; 41 Rank[i] = (i < len ? s[i] : -1); 42 } 43 for (k = 1; k <= len; k *= 2) 44 { 45 sort (sa,sa+len+1,cmp); 46 tmp[sa[0]] = 0; 47 for (int i = 1; i <= len; i++) 48 { 49 tmp[sa[i]] = tmp[sa[i-1]] + (cmp(sa[i-1],sa[i])? 1 : 0); 50 } 51 for (int i = 0; i <= len; i++) 52 Rank[i] = tmp[i]; 53 } 54 } 55 56 void Get_lcp() 57 { 58 for (int i = 0; i < len; i++) 59 Rank[sa[i]] = i; 60 int h = 0; 61 lcp[0] = 0; 62 for (int i = 0; i < len; i++) 63 { 64 int j = sa[Rank[i]-1]; 65 if (h > 0) 66 h--; 67 for (; h+i < len && h+j < len; h++) 68 if (s[i+h] != s[j+h]) 69 break; 70 lcp[Rank[i]] = h; 71 } 72 } 73 bool isdigit(char &ch) 74 { 75 return ch >= '0' && ch <= '9'; 76 } 77 int vec[maxn], board[maxn], tot; 78 int SUM[maxn]; 79 int solve (int l, int r) 80 { 81 if (l > r) 82 return 0; 83 int res ; 84 res = sum[r] - sum[l-1]; 85 res = ((res%mod)+mod)%mod; 86 res -= num[l-1] * SUM[r-l+1]; 87 res = ((res%mod)+mod)%mod; 88 return ((res%mod)+mod)%mod; 89 } 90 int main() 91 { 92 #ifndef ONLINE_JUDGE 93 freopen("in.txt","r",stdin); 94 #endif 95 int n; 96 SUM[1] = 10; 97 for (int i = 2; i < maxn; i++) 98 { 99 SUM[i] = (SUM[i-1] + 1) * 10 % mod; 100 } 101 while (~scanf ("%d", &n)) 102 { 103 s = "\0"; 104 tot = 0; 105 memset(sum, 0, sizeof(sum)); 106 memset(num, 0, sizeof(num)); 107 for (int i = 0; i < n; i++) 108 { 109 string tmp; 110 cin >> tmp; 111 s += tmp + "#"; 112 } 113 len = s.size(); 114 int val = 0; 115 for (int i = 0; i < len; i++) 116 { 117 if (s[i] != '#') 118 { 119 val = (val * 10 + s[i] - '0') % mod; 120 num[i] = val; 121 sum[i] = (sum[i-1] + num[i]) % mod; 122 board[i] = tot; 123 } 124 if (s[i] == '#') 125 { 126 vec[tot++] = i; 127 num[i] = val; 128 sum[i] = sum[i-1] + val; 129 } 130 } 131 build_sa(); 132 Get_lcp(); 133 int ans = 0; 134 for (int i = 0; i < len; i++) 135 { 136 int t1 = i + lcp[Rank[i]]; 137 if (s[i] == '0') 138 continue; 139 if (isdigit(s[i]) && i+lcp[Rank[i]] < vec[board[i]]) 140 { 141 int t2 = vec[board[i]] -1; 142 int ans1 = solve(i, t2); 143 int ans2 = solve(i , t1-1); 144 ans = (ans + solve(i, t2) - solve(i, t1-1)) % mod; 145 if (ans < 0) 146 ans += mod; 147 } 148 } 149 printf("%d\n", ans%mod); 150 } 151 return 0; 152 }View Code
?
1008:
題意:
很簡單的高中數學簽到題
思路:
略
代碼:
#include <set> #include <map> #include <cmath> #include <ctime> #include <queue> #include <stack> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef unsigned long long ull; typedef long long ll; const int inf = 0x3f3f3f3f; const double eps = 1e-8; double x, y; double p, q; double fun1() {double a1 = q*p*p*(x+y);double a2 = q*p*(1-p)*x;double a3 = q*p*(1-p)*y;double a4 = (1-q)*x;return a1+a2+a3+a4; } double fun2() {double a1 = (1-q) * p*p*(x+y);double a2 = (1-q)*p*(1-p)*x;double a3 = (1-q)*p*(1-p)*y;double a4 = (q)*y;return a1+a2+a3+a4;; } int main() {int t;cin>>t;while (t--){scanf ("%lf%lf%lf%lf",&x, &y, &p, &q);if (fun1() > fun2()){printf("tiger %.4f\n", fun1());}elseprintf("wolf %.4f\n", fun2());}return 0; }View Code
?
1011:
轉載于:https://www.cnblogs.com/oneshot/p/4398126.html
總結
以上是生活随笔為你收集整理的【2012天津区域赛】部分题解 hdu4431—4441的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 佛山小车车船税多少钱。我忘记交了要罚多少
- 下一篇: Log控制台打印设置