寒假训练2解题报告

1.CodeForces 112C

找一种可能满足其所给条件,为了让平方和尽可能大,那么我们总和总是取最大为y,分这个y时,尽可能少分这样得到的平方和才最大,所以其他元素都只分到1,留下一个最大元素,这里注意如果每个都分1不够分,直接表示无答案

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define ll long long
const int N = 100005;
int a[N];
int main()
{
   // freopen("a.in" , "r" , stdin);
    int n , y;
    ll x ;
    while(scanf("%d%I64d%d" , &n , &x , &y) == 3)
    {
        if(y < n){
            puts("-1");
            continue;
        }
        ll ans = 0;
        for(int i=1 ; i<=n ; i++) a[i]=1;
        a[1] = y-n+1;
        ans = (ll)a[1]*a[1] + (ll)(n-1);
        if(ans >= x){
            for(int i=1 ; i<=n ; i++)
                printf("%d\n" , a[i]);
        }
        else  puts("-1");
    }
    return 0;
}

2.CodeForces 112D

输出当前数的因子在其所给的前k个数中不存在的个数,我们用一个数组记录每一个因子上一次出现的位置,然后根据这个位置判断是不是在给定范围内出现

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
const int N = 100005;
int ans[N];
int vis[N];//记录最近被访问的时候

int main()
{
   // freopen("a.in" , "r" , stdin);
    int n,x,y;
    while(scanf("%d" , &n ) == 1)
    {
        memset(vis , 0 , sizeof(vis));
        memset(ans , 0 , sizeof(ans));
        for(int i=1 ; i<=n ; i++){
            scanf("%d%d" , &x , &y);

            int t = (int)sqrt(x+0.5);
          //  cout<<"t: "<<t<<endl;
            for(int j=1 ; j<=t ; j++){
                if(x % j == 0){
                    if(vis[j]<i-y) ans[i]++;
                    vis[j] = i;
                    int p = x/j;
                    if(p != j && vis[p]<i-y) ans[i]++;
                    vis[p] = i;
                }
            }
            printf("%d\n" , ans[i]);
        }
    }
    return 0;
}

3.CodeForces 112E

一道状态压缩p问题,这里可以理解为 一个  十字的图形可覆盖的加入到n*m中,问最少要多少个这样的十字图形

然后我们用1表示放置十字图形的中心,0表示没有放置十字图形的中心,每一行放十字图形的状态都只跟前两行有关,所以用dp[i][v][u]不断按行转移就好了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = (1<<6);
const int INF = 0x3f3f3f3f;

int dp[45][N][N];

void dfs(int i , int w , int v , int u , int k , int val)
{
    if(k<0){
        dp[i][v][u] = min(dp[i][v][u] , val);
        return ;
    }
    if(k>0 && !(v&(7<<(k-1))) && !(w&(1<<k))) dfs(i , w , v , u|(1<<k) , k-1 , val+1);
    else if(k==0 && !(v&(3<<(k))) && !(w&(1<<k))) dfs(i , w , v , u|(1<<k) , k-1 , val+1);
    else{
        dfs(i , w , v , u|(1<<k) , k-1 , val+1);
        dfs(i,w,v,u,k-1,val);
    }
}

bool ok(int u,int v,int k)
{
    for(int i=k ; i>=1 ; i--){
        if(!(v&(1<<i)) && !(u&(7<<(i-1)))) return false;
    }
    if(!(v&1) && !(u&3)) return false;
    return true;
}

int main()
{
   // freopen("a.in" , "r" , stdin);
    int n,m;
    while(scanf("%d%d" , &n , &m) == 2)
    {
        if(n<m) swap(n,m);
        if(n==1){
            int ans ;
            if(m%3 == 0) ans = m-m/3;
            else ans = m-1-m/3;
            printf("%d\n" , ans);
            continue;
        }
        memset(dp , 0x3f , sizeof(dp));
        dp[0][(1<<m)-1][0]=0;
        for(int i=1 ; i<=n  ; i++){
            for(int w=0 ; w<(1<<m) ; w++){
                for(int v=0 ; v<(1<<m) ; v++){
                    if(dp[i-1][w][v]<INF) dfs(i,w,v,0,m-1,dp[i-1][w][v]);
                }
            }
        }
        int ans = INF;
        for(int v=0 ; v<(1<<m) ; v++){
            for(int u=0 ; u<(1<<m) ; u++){
                if(dp[n][v][u]<INF && ok(u,v,m-1)){
                    ans = min(ans , dp[n][v][u]);
                }
            }
        }
        printf("%d\n" , n*m-ans);
    }
    return 0;
}

4.CodeForces 159E

离散化所有颜色,一个塔搭建可以是由 两个都为n个的颜色组成,或者一个为n一个为n+1

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <vector>
  6 #include <algorithm>
  7 using namespace std;
  8 const int N = 100005;
  9
 10 int a[N] ,  max_id[N] , sec_id[N]; //a[]保存离散化后的c
 11
 12 struct Node{
 13     int v , num;
 14 };
 15
 16 vector<Node> vec[N];
 17 #define  ll long long
 18 ll  max_val[N] , sec_val[N] , sum[N];
 19
 20 struct Cube{
 21     int c , s , num;
 22     bool operator<(const Cube &m)const{
 23         if(c == m.c) return s > m.s;
 24         return c < m.c;
 25     }
 26 }cu[N];
 27
 28 int bin_search(int x , int k)
 29 {
 30     int l=0 , r = k-1;
 31     while(l<=r){
 32         int m=(l+r)>>1;
 33         if(a[m] == x) return m;
 34         else if(a[m]>x) r = m-1;
 35         else l = m+1;
 36     }
 37 }
 38
 39 int main()
 40 {
 41   //  freopen("a.in" , "r" , stdin);
 42     int n;
 43     while(scanf("%d" , &n ) == 1)
 44     {
 45         for(int i=0 ; i<=n ; i++) vec[i].clear();
 46
 47         for(int i = 0 ;i<n ; i++)
 48         {
 49             scanf("%d%d" , &cu[i].c , &cu[i].s);
 50             cu[i].num = i+1;
 51         }
 52
 53         sort(cu , cu+n);
 54         int k = 0;
 55         a[k++] = cu[0].c;
 56         for(int i=1 ; i<n ; i++){
 57             if(cu[i].c != cu[i-1].c) a[k++] = cu[i].c;
 58         }
 59
 60         memset(sum , 0 , sizeof(sum));
 61         memset(max_val , 0 , sizeof(max_val));
 62         memset(sec_val , 0 , sizeof(sec_val));
 63         for(int i=0 ; i<n ; i++){
 64             int index = bin_search(cu[i].c , k);
 65             Node node;
 66             node.num = cu[i].num , node.v = cu[i].s;
 67             vec[index].push_back(node);
 68             sum[index] = sum[index] + cu[i].s;
 69             int len = vec[index].size();
 70             if(max_val[len] < sum[index]){
 71                 sec_val[len] = max_val[len];
 72                 sec_id[len] = max_id[len];
 73
 74                 max_val[len] = sum[index];
 75                 max_id[len] = index;
 76             }
 77             else if(sec_val[len] < sum[index]){
 78                 sec_val[len] = sum[index];
 79                 sec_id[len] = index;
 80             }
 81         }
 82        // cout<<"test: "<<max_val[1]<<" index: "<<max_id[1]<<" "<<sec_id[1]<<endl;
 83         int col1 , col2 , len1 , len2;
 84         ll ans = 0;
 85         for(int len=1 ; len<=n ; len++){
 86             if(max_val[len] && sec_val[len]){
 87                 if(max_id[len] != sec_id[len]){
 88                     if(ans < max_val[len]+sec_val[len]){
 89                         ans = max_val[len]+sec_val[len];
 90                         col1 = max_id[len];
 91                         col2 = sec_id[len];
 92                         len1 = len , len2 = len;
 93                     }
 94                 }
 95             }
 96             if(max_val[len] && max_val[len+1]){
 97                 if(max_id[len] != max_id[len+1]){
 98                     if(ans < max_val[len]+max_val[len+1]){
 99                         ans = max_val[len]+max_val[len+1];
100                         col1 = max_id[len];
101                         col2 = max_id[len+1];
102                         len1 = len , len2 = len+1;
103                     }
104                 }
105             }
106             if(sec_val[len] && max_val[len+1]){
107                 if(sec_id[len] != max_id[len+1]){
108                     if(ans < sec_val[len]+max_val[len+1]){
109                         ans = sec_val[len]+max_val[len+1];
110                         col1 = sec_id[len];
111                         col2 = max_id[len+1];
112                         len1 = len , len2 = len+1;
113                     }
114                 }
115             }
116             if(max_val[len] && sec_val[len+1]){
117                 if(max_id[len] != sec_id[len+1]){
118                     if(ans < max_val[len]+sec_val[len+1]){
119                         ans = max_val[len]+sec_val[len+1];
120                         col1 = max_id[len];
121                         col2 = sec_id[len+1];
122                         len1 = len , len2 = len+1;
123                     }
124                 }
125             }
126         }
127
128         printf("%I64d\n%d\n" , ans , len1+len2);
129         printf("%d" , vec[col2][0].num);
130         for(int i=0 ; i<len1 ; i++){
131             printf(" %d" , vec[col1][i].num);
132             if(i+1<len2) printf(" %d" , vec[col2][i+1].num);
133         }
134         puts("");
135     }
136     return 0;
137 }

时间: 2024-10-12 20:18:19

寒假训练2解题报告的相关文章

寒假训练5解题报告

1.HDU 1114 Piggy Bank 一道简单的背包问题 #include <iostream> #include <cstdio> #include <cstring> using namespace std; #define ll long long const int N = 10005; const int INF = 0x3f3f3f3f; int dp[N]; int main() { // freopen("a.in" , &qu

寒假训练3解题报告 CodeForces #148

CodeForces 148B 一道简单模拟,判断龙能够抓到公主几次,如果公主和龙同时到达公主的城堡,不算龙抓住她,因为路程除以速度可能会产生浮点数,所以这里考虑一下精度问题 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <iomanip> 5 #include <algorithm> 6 using namespace std; 7 #defi

寒假训练4解题报告

1.        Cosmic Tables 数据量比较大,这里不能直接暴力,用行指针和列指针表示当前行列是原来的第几行第几列 #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int N = 1005; int n ,m , k , row[N] , col[N] , a[N][N]; char s[5] ; int p1 , p2; int mai

寒假训练1解题报告

1.CodeForces 92A 给一堆围成圈的小朋友发饼干,小朋友为1~n号,第几号小朋友每次拿多少块饼干,问最后剩多少饼干 #include <iostream> #include <cstdio> using namespace std; int main() { // freopen("a.in" , "r" , stdin); int n , m; while(scanf("%d%d" , &n , &a

广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告

题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途中,之前已经走过Cityc(可能会等于a),那么就可以交p的钱,否则之前未走过Cityc,就一定要交r 的路费啦. 注意,一个点可以被反复多次走,也就是可能构成环,虽然路走长了,但路费便宜了,这个问题要考虑到.还有就是剪枝啦:如果当前求得的路费比以前求得的答案要大,那就要回溯. mincost 明明

CSU-ACM2014暑假集训基础组训练赛(1) 解题报告

•Problem A HDU 4450                 水题,签到题 水题..没啥好说的.给大家签到用的. 1 #include <cstdio> 2 int main(){ 3 int n,a,ans; 4 while(scanf("%d",&n),n){ 5 ans = 0; 6 for(int i = 0;i < n;i++){ 7 scanf("%d",&a); 8 ans += a*a; 9 } 10 pr

CSU-ACM暑假集训基础组训练赛(4)解题报告

•Problem A SPOJ SUB_PROB   AC自动机 •题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过? •几乎和周一课件上的第一个例题一模一样.. •把文本串丢到AC自动机里面去跑. •注意: •1.可能有两个相同的模式串(略坑吧.) •2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”. 1 #include <ios

「csp校内训练 2019-10-24」解题报告

「csp校内训练 2019-10-24」解题报告 T1.猴猴吃苹果 \(Description\) 猴猴最喜欢在树上玩耍,一天猴猴又跳上了一棵树,这棵树有 \(N \ (N \leq 50000)\) 个苹果,每个苹果有一个编号,分别为 \(0\) ~ \(N - 1\) 它们之间由 \(N-1\) 个树枝相连,猴猴可以从树枝的一端爬到树枝的另一端,所以猴猴可以从任意一个苹果的位置出发爬到任意猴猴想去的苹果的位置. 猴猴开始在编号为 \(K \ (K < N)\) 的苹果的位置,并且把这个苹果吃

「csp校内训练 2019-10-30」解题报告

「csp校内训练 2019-10-30」解题报告 T1.树 题目链接(逃) \(Description\): 现在有一棵树,共 \(N\) 个节点. 规定:根节点为 \(1\) 号节点,且每个节点有一个点权. 现在,有 \(M\) 个操作需要在树上完成,每次操作为下列三种之一: \(1 \ x \ a\):操作 \(1\),将节点 \(x\) 点权增加 \(a\). \(2 \ x \ a\):操作 \(2\),将以节点 \(x\) 为根的子树中所有点的权值增加 \(a\). \(3 \ x\)