HDU 2061-2080

版权声明: https://blog.csdn.net/weixin_39778570/article/details/82530888

题目集合:http://acm.hdu.edu.cn/listproblem.php?vol=11
2061 Treasure the new start, freshmen!

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i)

int t,n;
double ans, crd, sco, c_sum, cs_sum;
char s[40];
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d", &n);
        bool flat = 1;
        c_sum=0, cs_sum=0;
        fo(i, 1, n){
            scanf("%s%lf%lf", s, &crd, &sco);
            if(sco<60) flat = 0;
            c_sum += crd;
            cs_sum += crd*sco;
        }
        ans = cs_sum/c_sum;
        if(t>=1 && !flat) printf("Sorry!\n\n");
        else if(!flat)   printf("Sorry!\n");
        else if(t>=1) printf("%.2f\n\n", ans);
        else    printf("%.2f\n", ans);
    }
    return 0;
}

2062 Subset sequence
/* 找规律,找方程 */
{1}
{1,2}
{1,2,3}
{1,3}
{1,3,2}

{2}
{2,1}
{2,1,3}
{2,3}
{2,3,1}

{3}
{3,1}
{3,1,2}
{3,2}
{3,2,1}

这到题的集合排序是这样子的 字典排序 头大则大 头小则小 不优先考虑长度

f(n) 表示按字典排序的集合总数 g(n) 表示每个小组的集合数量
f(n) = (f(n-1)+1) * n
g(n) = f(n)/n
= f(n-1)+1
g(n-1) = f(n-1)/(n-1)
g(n) = g(n-1)*(n-1) + 1

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n, m, g[22], t, a[22];
void init(){
    // 数量为n的分组长度表
    g[1] = 1;
    for(int i=2; i<=21; ++i){
        g[i] = (g[i-1]) * (i-1) + 1;
    }
}
int main(){
    init();
    while(scanf("%lld%lld", &n, &m)!=EOF){
        for(int i=1; i<=20; i++) a[i] = i;
        while(n){
            t = (m-1) / g[n] + 1; // 在n个数的字典集合中,m在第t组 
            printf("%d", a[t]); 
            for(int i=t; i<=20; i++) a[i] = a[i+1]; // 比输出数字大的要左移一位, 比如,如果现在是第2组,那么下该组下的第2组就是3,第3组就是4 
            m -= (t-1) * g[n] + 1; // 需要减去前面的组数量以及头部空集,得到在新的组里是第几个数 
            if(m<=0) { printf("\n");break; }
            else       printf(" ");
            --n; // 集合规模减1,问题规模缩小 
        }
    }
    return 0;
} 

2063 过山车
二分图 最大匹配问题

#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i) 
#define ll long long
using namespace std;
int k, m, n, ok[1001][1001], vis[1001], cx[1001], cy[1001];

int dfs(int u){ // 从女生出发,扩充路径 
    fo(v,1,n){
        if(ok[u][v] && !vis[v]){
            vis[v] = 1;
            if(cy[v]==-1 || dfs(cy[v])){
                cy[v] = u; cx[u] = v;
                return 1;
            }
        }
    } 
    return 0;
}
// 打印匹配结果 
void PP(){
    fo(v,1,m){
        if(cx[v]!=-1) printf("[%d, %d]\n", v,cx[v]);
    }
} 
ll maxmatch(){
    ll ans = 0;
    fo(u,1,m){ // 起点是女生,故最多有女生数量的路径数 
        memset(vis,0,sizeof(vis));
        ans += dfs(u);
    }
    //PP();
    return ans;
}
int main(){
    scanf("%d", &k);
    while(k){
        scanf("%d%d",&m,&n);
        memset(ok,0,sizeof(ok));
        memset(cx,-1,sizeof(cx));
        memset(cy,-1,sizeof(cy));
        int t1,t2;
        fo(i,1,k){
            scanf("%d%d",&t1,&t2);
            ok[t1][t2] = 1; // 女到男 
        }
        printf("%lld\n",maxmatch());
        scanf("%d", &k);
    }
    return 0;
}

2064 汉诺塔III
/*
f(n) 表示 从 a 到 c 的总数
f(n-1) 已求
那么f(n)则需要 n-1 个从a移动到c
第n个从a到b n-1 个又从c到a
第n个从b到c n-1 个又从a到c
共 2 + 3f(n-1) 次
故f(n) = 3*f(n-1) + 2
推导公式:
f(n)+1 = 3*(f(n-1)+1)
又首项 f(1) + 1 = 3
故f(n)+1 是以3为首项 公比为3的等比数列
故 f(n)+1 = 3^n
f(n) = 3^n -1
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll m_pow(ll x, ll n){
    ll res = 1;
    while(n){
        if(n&1) res *= x;
        x *= x;
        n >>= 1;
    }
    return res;
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF) printf("%lld\n", m_pow(3,n)-1);
}

2065 “红色病毒”问题 :https://blog.csdn.net/weixin_39778570/article/details/822561284
2066 一个人的旅行

#include<bits/stdc++.h> 
#define fo(i, j, n) for(int i=j; i<=n; ++i)
#define ll long long
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1005;
typedef pair<int, int> P;

struct edge{
    int to, cost;
};
int V = 1000; // 顶点数 
vector<edge> G[N];
int d[N];
void dijkstra(int s){
    priority_queue< P, vector<P>, greater<P> > que;
    fill(d, d+V+2, INF);
    d[s] = 0;
    que.push(P(0,s));
    while(!que.empty()){
        P p = que.top();
        que.pop();
        int v = p.second;
        if(d[v] < p.first) continue; //到v点的距离如果已经被更新 这无须执行以下操作
        for(auto e : G[v]){
            if(d[e.to] > d[v]+e.cost){
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to], e.to));
            }
        }       
    }
}
int T,S,D;
int main(){
    int from, to, cost;
    while(scanf("%d%d%d", &T,&S,&D) != EOF){
        for(int i=0; i<N; i++) G[i].clear();
        fo(i, 1, T){
            scanf("%d%d%d",&from,&to,&cost);
            edge var;
            var.to = to; var.cost = cost;
            G[from].push_back(var);
            var.to = from; var.cost = cost;
            G[to].push_back(var);
        }
        fo(i, 1, S){ // 多个地点问题 
            scanf("%d", &to);
            edge var;
            var.to = to; var.cost = 0;
            G[0].push_back(var);
        }
        dijkstra(0);
        int ans = INF;
        fo(i,1,D){
            scanf("%d", &to);
            if(d[to]<ans) ans = d[to];
        }
        printf("%d\n", ans);
    } 

    return 0;
}

2067 小兔的棋盘
/卡塔兰数,大数用java做/

C(2n , n)/( n+1 )
kf[i] = kf[i-1]*1.0/(i+1)*(4*i-2);  
这条公数用来做大数的 
Catalan[i] += Catalan[j] * Catalan[i - 1 - j];
小于35的数据 
/*dp做法*/
#include<bits/stdc++.h>
#define fo(i,j,n) for(int i=j; i<=n; ++i)
#define ll long long
using namespace std;
int n;
ll dp[40][40];
void init(){
    // 初始化第0行为1
    fo(j, 0, 35) dp[0][j] = 1;
    fo(j, 1, 35){ // 列 
        fo(i, 1, j){ //if(i==j) dp[i][j] = dp[i-1][j];
            else dp[i][j] = dp[i-1][j] + dp[i][j-1];
        //  printf("%d %d %lld\n", i, j, dp[i][j]);
        }
        printf("%lld\n",dp[j][j]);
    }
}
int main(){
    init();
    int cnt=0;
    while(scanf("%d", &n)&&n!=-1){
        printf("%d %d %I64d\n", ++cnt, n, dp[n][n]*2);
    }
}
import java.math.BigInteger;
import java.util.Scanner;

public class 卡塔兰数 {
    static BigInteger[] kf = new BigInteger[40];
    static void init() {
        kf[1] = new BigInteger("1");
        BigInteger one = new BigInteger("1");
        BigInteger two = new BigInteger("2");
        BigInteger four = new BigInteger("4");
        for(int i=2; i<=35; ++i) {
            String str = String.valueOf(i);
            BigInteger n = new BigInteger(str);
            kf[i] = (n.multiply(four).subtract(two)).multiply(kf[i-1]).divide(n.add(one));
        }
        for(int i=1; i<=35; i++) kf[i] = kf[i].multiply(two);
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int cnt = 0;
        init();
        while(sc.hasNext()) {
            int n = sc.nextInt();
            if(n==-1)break;
            System.out.println(++cnt+" "+n+" "+kf[n].toString());
        }
    }
}

2068 RPG的错排
组合 + 错排

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;

ll dd[30];
ll c[30][30];
void CC(){
    c[0][0] = 1;
    fo(i, 1, 25){
        fo(j, 0, i){
            if(j==0 || i==j) c[i][j] = 1;
            else c[i][j] = c[i-1][j] + c[i-1][j-1];
        //  printf("%lld\n",c[i][j]);
        }
    }
}
void init(){
    dd[0]=1, dd[1] = 0,dd[2] = 1; // dd[0]要设置成1因为下面要乘到 
    fo(i,3,25) dd[i] = (i-1)*(dd[i-1]+dd[i-2]);
//  fo(i,1,25) printf("%I64d\n", dd[i]);  这里其实会溢出,但还AC了。。。 
}
int main(){
    init();
    CC();
    int n;
    while(scanf("%d", &n)&&n!=0){
        int mid = n >> 1; // 小于等于一半人 
        ll ans = 0;
        fo(k,0,mid){
        //  printf("%d\n", k);
            ans += c[n][k]*dd[k];
        }
        printf("%lld\n", ans);
    }
    return 0;
}

2069 Coin Change
硬币组合问题 dp

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;
const int N = 300;
ll dp[300][105];
ll ans [300];
void init(){
    dp[0][0] = 1;
    int coins[5] = {50,25,10,5,1};
    fo(k, 0, 4){           // 第几个硬币 
        fo(i, 1, 250){     // 钱数 
            fo(j, 1, min(100,i)){ // 硬币数,银币数不会大于钱数,最多100个硬币
                if(i>=coins[k]) dp[i][j] += dp[i-coins[k]][j-1];
            }
        }
    }
    ans[0] = 1; 
    fo(i,1,250){
        fo(j,0,min(100,i)) ans[i] += dp[i][j];
    }
} 
int main(){
    init();
    int n;
    while(scanf("%d", &n)!=EOF){
        printf("%lld\n", ans[n]); 
    }
    return 0;
}

2070 Fibbonacci Number

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;

ll fb[51];
void init(){
    fb[0] = 0; fb[1] = 1;
    fo(i,2,50){
        fb[i] = fb[i-1] + fb[i-2];
    //  printf("%lld\n", fb[i]);
    }
}

int main(){
    init();
    int n;
    while(scanf("%d",&n) && n!=-1) printf("%lld\n", fb[n]);
    return 0;
} 

2071 Max Num

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;
int t,n;
int main(){
    scanf("%d",&t);
    while(t--){
        double a,max = 0.0;
        scanf("%d", &n);
        fo(i,1,n){
            scanf("%lf", &a);
            if(a>max)max=a;
        }
        printf("%.2f\n",max);
    }
    return 0;
}

2072 单词数

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;

map<string,int> mp;
int main(){
    string str,st;
    while(getline(cin,str)&&str!="#"){
        mp.clear();
        stringstream ss(str);
        while(ss>>st) mp[st]++;
        printf("%d\n", mp.size()); 
    }

    return 0;
}

2073 无限的路
/注意数组开大点! 99*99这个点要在线上,所以要开198至少/

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;

double d[100000],ans;
double dd[250][250];
void init(){
    d[0] = 0.0, d[1] = 1.0;
    dd[0][0] = 0, dd[0][1] = 1.0;
    double m = sqrt(2);
    int now = 2, k;
    fo(i,1,200){
        k = i;
        fo(j,1,i){
            d[now] = d[now-1] + m;
            dd[j][--k] = d[now];
//          cout << j << "  " << k <<" "<< dd[j][k] << endl;
            now++;
        }
        d[now] = d[now-1] + sqrt(i*i+(i+1)*(i+1)); // 注意啦,这里是从一排过度到另一排的斜线
        dd[0][i+1] = d[now];
//      cout << 0 << "  " << i+1 << " " <<dd[0][i+1] << endl;
        now++;
    } 
}
int n,x1,y1,x2,y2;
int main(){
    init();
    scanf("%d", &n);
    while(n--){
        scanf("%d%d%d%d", &x1,&y1,&x2,&y2);
        ans = abs(dd[x1][y1]-dd[x2][y2]);
        printf("%.3f\n", ans);
    }
    return 0;
} 

2074 叠筐

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;
char s[100][100];

void PP(int n, char a, char b){
    if(n==1){printf("%c\n", a);return;}
    memset(s,0,sizeof(s));
    int mid = n/2;
    s[mid][mid] = a;
    int p = mid-1;
    int q = mid+1;
    char c = a;
    while(p>=0){
        if(c==a)c=b;else c=a;
        s[mid][p--] = s[mid][q++] = c;
    }   
//  printf("%s\n", s[mid]);
    int k = 1;
    c = a;
    for(int i=mid-1; i>=0; --i){
        strcpy(s[i], s[mid]);
        p = mid-1;
        q = mid+1;
        if(c==a)c=b;else c=a;
        s[i][mid]=c;
        fo(j,1,k){
            s[i][p--] = s[i][q++] = c;
        }   
        k+=1;   
    //  printf("%s\n", s[i]);
    }
    printf(" ");
    fo(i,1,n-2) printf("%c",s[0][i]);
    printf(" \n");
    fo(i,1,mid) printf("%s\n",s[i]);
    for(int i=mid-1; i>0; --i)printf("%s\n",s[i]);
    printf(" ");
    fo(i,1,n-2) printf("%c",s[0][i]);
    printf(" \n");
}
int main(){ 
//  PP(11,'B','A');
//  PP(5,'@','W');
    int n;
    char a, b;
    int flat = 0;
    while(~scanf("%d %c %c",&n,&a,&b)){
        if(flat) printf("\n");
        else flat=1;
        PP(n,a,b);
    }    
    return 0;
}

2075 A|B?

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T, a, b;
int main(){
    cin >> T; 
    while(T--){
        cin >> a >> b;
        if(a%b==0) puts("YES");
        else puts("NO");     
    }
    return 0;
}

2076 夹角有多大(题目已修改,注意读题)

#include<bits/stdc++.h>
#define ll lnog long
#define fo(i, j ,n) for(int i=j; i<=n; ++i)
using namespace std;
int T, h, m, s;
int ans;
int main(){
    scanf("%d", &T); 
    while(T--){
        scanf("%d%d%d", &h,&m,&s);
        if(h>=12) h-=12; // 注意不是24小数制的哈 
        double m1 = m + 1.0*s / 60;
        double t1 = h*5 + m1/12;
        double d = abs(t1-m1);
        double dd = min(d, 60-d);
        ans = dd*6/1;
        printf("%d\n", ans);
    } 
    return 0;
}

2077 汉诺塔IV
n-1个到第二个柱子,n(最大)个到第2个柱子再到第3个柱子,n-1和从第二个柱子到第三个柱子
f(n) = 3^n-1 -1 + 2 = 3^n-1 + 1

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j ,n) for(int i=j; i<=n; ++i)
using namespace std;

ll pow_mod(ll x, ll n){
    ll res = 1;
    while(n){
        if(n&1) res *= x;
        x *= x;
        n >>= 1;
    }
//  cout << res << endl;
    return res;
}
int T,n;
ll ans;
int main(){
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        ans = pow_mod(3,n-1) + 1;
        printf("%I64d\n", ans);
    } 
    return 0;
} 

2078 复习时间

#include<bits/stdc++.h>
#define ll long long 
#define fo(i, j, n) for(int i=j; i<=n; ++i)

using namespace std;
int t,a[50],ans;
int main(){
    scanf("%d",&t); 
    while(t--){
        memset(a,0,sizeof(a));
        int n,m;
        scanf("%d %d", &n,&m);
        fo(i,0,n-1) scanf("%d", &a[i]);
        sort(a,a+n);
        ans = (100-a[0])*(100-a[0]);
        printf("%d\n",ans); 
    }
    return 0;
} 

2079 选课时间
/组合问题 母函数模板/
/*
a保存结果,b中间结果
v权值 n1初始数量 n2终止数量
*/

#include<bits/stdc++.h>
#define ll long long
#define fo(i, j, n) for(int i=j; i<=n; ++i)
using namespace std;

int t,n,k,last,last2;
int a[1000],b[1000];
int v[10],n2[10];  // 权值,终止数量 
int main(){
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n,&k);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(v,0,sizeof(v));
        memset(n2,0,sizeof(n2));

        fo(i, 0, k-1) scanf("%d %d", &v[i], &n2[i]);

        a[0]=1;
        last = 0;
        fo(i,0,k-1){ // 第i个括号 
            last2 = last + n2[i]*v[i];    // 目前最远项 
            memset(b,0,sizeof(int)*(last2+1));
            for(int j=0; j<=n2[i]; j++){         // 遍历第i个括号的每一项 
                for(int k=0; k<=last; k++){  // 遍历a的每一项 
                    b[k+j*v[i]] += a[k];
                }
            }
            memcpy(a,b,sizeof(int)*(last2+1));
            last = last2;
        }

        printf("%d\n", a[n]);
    }
    return 0;
}

2080 夹角有多大II

#include<bits/stdc++.h>
#define ll long long
#define PI 3.141592
using namespace std;
int t;
double x1,y1,x2,y2;
double a2, b2, c2, cosC, ans;
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%lf %lf %lf %lf", &x1,&y1,&x2,&y2);
        a2 = x1*x1+y1*y1;
        b2 = x2*x2+y2*y2;
    //  cout<< a2 << "\n" << b2<<endl;
        c2 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
        cosC = (a2+b2-c2)/(2*sqrt(a2)*sqrt(b2));
    //  cout << cosC << endl;
        ans = acos(cosC)*180/PI;
        printf("%.2f\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39778570/article/details/82530888
hdu