A.Seinfeld
http://acm.hdu.edu.cn/showproblem.php?pid=3351
用num来标记次数,用len来表示 { 的个数 从前开始遍历字符串,如果是 { 就不配对 ,len++,如果是 } 且如果len不为0就len--,在此情况下如果len为零了,就只能将此字符变成 { ,那么num++;遍历完了,如果len不为0就说明剩下了 { 没有配对 此时只需要 num+=len/2即可;

#include <fstream> #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <list> #include <set> #include <map> #include <algorithm> #include <string> #include <cstring> using namespace std; int n0,n1,n2,n3,n4; int main() { string s; int i,k,num,len; for(k=1;;k++) { cin>>s; if(s[0]=='-') break; num=0; len=0; for(i=0;i<s.size();i++) { if(s[i]=='{') len++; else { if(len) len--; else { num++; s[i]='{'; len=1; } } } if(len>0) num+=len/2; cout<<k<<'.'<<' '<<num<<endl; } return 0; }
B.Tiles of Tetris, NOT!
http://acm.hdu.edu.cn/showproblem.php?pid=3352
就是问最少用多少个矩形能拼成一个面积最小的正方形。num=最小公倍数/a*最小公倍数/b。

#include <fstream> #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <list> #include <set> #include <map> #include <algorithm> #include <string> #include <cstring> using namespace std; int gcd(int a,int b) { int c; if(a==0) return b; while(b!=0) c=b,b=a%b,a=c; return a; } int main() { long long a,b; while(cin>>a>>b) { if(a==0&&b==0) break; int c=gcd(a,b); long long d=a*b/c/c; cout<<d<<endl; } return 0; }
C.Not So Flat After All
http://acm.hdu.edu.cn/showproblem.php?pid=3353
分别把两个数分解质因数为p1^a1*p2^a2......的形式。维度就是两个数需要的所有素数,距离就是两个数所有质因数的a1、a2...的差的和。

#include <fstream> #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <list> #include <set> #include <map> #include <algorithm> #include <string> #include <cstring> using namespace std; #define MAX 1000000 int noprime[MAX]; int pp[2][MAX]; int numm[MAX]; //出现几个素数 int numnum; int vis[MAX]; int b[2]; int Max(int a,int b) { return a>b?a:b; } int Min(int a,int b) { return a<b?a:b; } void Prime(int n) //筛法求素数 { int k; noprime[0]=noprime[1]=1; noprime[2]=0; for (int i=2;i<n;i++) if (!noprime[i]) { k=i; while(k+i<n) { k=k+i; noprime[k]=1; } } } void find_prime_factor(int n) { int k=b[n]; for (int i=2;i<=k;i++) if (!noprime[i]) { if (k%i==0) { if (!vis[i]) { vis[i]=numnum+1; numm[numnum]=i; numnum++; } while (k%i==0) { k/=i; pp[n][vis[i]-1]++; } } } return; } int main() { int caseo=1; Prime(1000000); while(cin>>b[0]>>b[1]) { if (b[0]==0 && b[1]==0) return 0; memset(pp,0,sizeof(pp)); memset(numm,0,sizeof(numm)); memset(vis,0,sizeof(vis)); numnum=0; find_prime_factor(0); find_prime_factor(1); cout<<caseo++<<". "<<numnum<<":"; int ans=0; for (int i=0;i<numnum;i++) { ans+=abs(pp[0][i]-pp[1][i]); } cout<<ans<<endl; } return 0; }
D.Probability One
http://acm.hdu.edu.cn/showproblem.php?pid=3354
简单题,模拟即可。

#include <fstream> #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <list> #include <set> #include <map> #include <algorithm> #include <string> #include <cstring> using namespace std; int n0,n1,n2,n3,n4; int main() { int caseo=1; while(cin>>n0,n0) { n1=n0*3; if (n1%2==1) n2=(n1+1)/2; else n2=n1/2; n3=3*n2; n4=n3/9; if (n1%2==1) { string s="odd"; cout<<caseo++<<". "<<s<<" "<<n4<<endl; } else { string s="even"; cout<<caseo++<<". "<<s<<" "<<n4<<endl; } } return 0; }
G.Stock Chase(难)
http://acm.hdu.edu.cn/showproblem.php?pid=3357
// 【题意】
// 有N个公司,A公司可以买B公司的股票
// B公司可以买C公司的股票,如此A公司会间接持有C公司的股票
// 只要A公司直接或者间接持有了X公司的股票,X公司就不能购买A公司的股票,这种操作非法
// 按照时间顺序给出T次购买请求,问有多少次非法的购买请求会被回绝
// 【思路】
// 传递闭包
// 每个query后加入一条边,计算新的传递闭包
// 由于每次query前,G都是一个传递闭包,所以可以直接看是否有逆向弧来判断是否query合法
// 时间复杂度肉眼看是O(T*N*N),T是查询次数,N是节点数
// 理论上铁超时,但是实际上G很快会达到一种“饱和”的状态,大部分的query都是马上得到结果

#include <fstream> #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <list> #include <set> #include <algorithm> #include <string> #include <cstring> using namespace std; #define MAXN 235 bool conn[MAXN][MAXN]; std::vector<int> vconn[MAXN]; int N, T; int main() { int kase = 1; int i, k; int v; for (i = 1; i <= MAXN; i++) vconn[i].reserve(MAXN); while (scanf("%d %d", &N, &T), N || T) { memset(conn, 0, sizeof(conn)); for (i = 1; i <= N; i++) { // 注意有自己到自己的弧,这样做是为了方便算传递闭包,算之前应该对i==i做特判 vconn[i].resize(0); vconn[i].push_back(i); conn[i][i] = true; } int a, b; int res = 0; while (T--) { scanf("%d %d", &a, &b); if (a == b || conn[b][a]) { res ++; continue; } if (conn[a][b]) continue; for (i = 1; i <= N; i++) { // 没有到a的弧或者已经有到b的弧 if (!conn[i][a] || conn[i][b]) continue; // 到a有弧,到b没弧 for (k = vconn[b].size()-1; k >= 0; k--) { v = vconn[b][k]; if (conn[i][v]) continue; conn[i][v] = true; vconn[i].push_back(v); } } } printf("%d. %d\n", kase++, res); } return 0; }
K.Hex-a-bonacci
http://lightoj.com/volume_showproblem.php?problem=1006
这道题挺有意思的。如果直接复制代码(刚开始就以为是这样一道用来搞笑的题。。。)递归fn重复计算太多要超时,把它放到数组里存起来就好了

#include <fstream> #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <iomanip> #include <iomanip> #include <climits> #include <vector> #include <stack> #include <queue> #include <list> #include <set> #include <map> #include <algorithm> #include <string> #include <cstring> using namespace std; int a, b, c, d, e, f; int ffn[10005]; int fn( int n ) { if( n == 0 ) return a; if( n == 1 ) return b; if( n == 2 ) return c; if( n == 3 ) return d; if( n == 4 ) return e; if( n == 5 ) return f; return( ffn[n-1] + ffn[n-2] + ffn[n-3] + ffn[n-4] + ffn[n-5] + ffn[n-6] ); } int main() { int n, caseno = 0, cases; scanf("%d", &cases); while( cases-- ) { scanf("%d %d %d %d %d %d %d", &a, &b, &c, &d, &e, &f, &n); for (int i=0;i<=n;i++) ffn[i]=fn(i)% 10000007; printf("Case %d: %d\n", ++caseno, ffn[n] % 10000007); } return 0; }