2017icpc全国邀请赛(陕西)

赛后总结

首先想吐槽一下天花板会掉的酒店和自带不明黄色痕迹的床单
算了还是直接进入主题吧…..
热身赛爆零了,一道猜题意一道是二分贪心,一道是数位dp+数论,cf上面的题,强肛二分贪心结果没肛出来,真是蠢的不行.
正赛打的也很难看,先看到J题签到直接输出一个坐标就OK,
然后是B题,题意是给我们一个序列,然后可以把序列中任意两个数字进行交换,最多交换k次,求能够得到的最大连续子段和.一开始往DP那方面去想,但是没什么思路,而且当时已经过穿了的题目,后来灵机一动,枚举任意一个区间,然后把区间内前k小的数字和区间外前k大的数字进行交换.然后求一个最大值即可.
接下来是C题,队友想的,方法大概就是一个简单的贪心,没什么特别复杂的情况,直接贪心暴力就行,不过有个地方我觉得很可能会TLE,但是赛后出题人表示就是给一道简单的贪心签到,没造这种数据.过完三个题一个半小时吧当时是48名,银牌都没压力铜更是稳的不行,对于一个铁牌选手来说我当时心里已经非常激动,心态完全爆炸不太想写题目,这也导致我们后面直接崩溃.
A题题意是有一个一行n列的01矩阵A,和一个n*m的01矩阵B,给定这两个矩阵相乘后的矩阵(mod2),求A和B矩阵有多少种组合方案
三个小时没什么结果,还剩几十分钟的时候我仔细想一下想到枚举A里面的1的个数然后开始组合数乱搞,但是时间毕竟太紧了没写出来感觉好气,赛后想到公式应该是(2^n - 1) * (2 ^ (n * m - m)) 如果给定的矩阵是全0,则还要加上一个2^(m*n)
K题题意是一个人要去参加一个婚礼,目的地在坐标轴一个点上,当前在0点处,从一个点跳到下一个点需要一个单位时间,然后数轴上有一些点,可以向前跳yi步,但是要求必须连续走了zi步,问到达目的地的最少时间,(只能往前走不能往后走,总共10万个点)
出题人说这个题怎么最短路和dp都行,最短路建边应该不是很复杂,堆优化一些dijkstra应该就可以了,具体没想,想了一个dp方程
虽然数轴的数字比较大,有1e9,但是实际上我们只关心那些能跳的点,它要从哪里开始连续走,然后可以跳到哪里,因此实际上只有最多30万个点.
对于每一个点,它可以由前面的点走过来即,dp[i] = min(dp[j] + x[i] - x[j] )(0<= j < i)
同时i点可能由前面某些点跳到,枚举那些能跳到他的点j dp[i] = min(dp[i] , dp[j - zj] + zj) (这个地方要用map哈希一下),
虽然还没交(目前为止没有地方可以交),但是感觉应该差不多了,把代码贴一下 等什么时候能交的时候交一下看看.

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define  LONG long long
const int   INF=0x3f3f3f3f;
const LONG  MOD=1e9+ 7;
const double PI=acos(-1.0);
#define clrI(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
#define lson  l , mid , rt<< 1
#define rson  mid + 1 ,r , (rt<<1)+1
#define root 1, m , 1
struct Node
{
    int x , y ,z ;
}node[100100] ;
int point[400400] ;
int tmp[400400] ;
int L ;
int dp[400400] ;
int F[400400] ;
int main()
{
    int T ;
    cin >> T ;
    while(T --)
    {
        int n ;
        scanf("%d%d",&n , &L) ;
        for(int i = 1; i <= n ; ++i)
        scanf("%d%d%d",&node[i].x, &node[i].y , &node[i].z) ;
        map<int , int >mp1 ;
        map<int , int >mp;
        map<int , int > jump ;
        map<int , int >mp2 ;
        jump.clear() ;
        mp1.clear() ;
        mp.clear() ;
        mp2.clear() ;
        int tot = 0 ;
        for(int i = 1 ; i<= n ;++i)
        {
            int _x1 ,_x2 ,_x3;
            int j1 =0 , j2 = 0 , j3 = 0 ;
            //
            _x1 = node[i].x ;
            if(_x1 >= 0 && _x1 <= L)
            tmp[++tot] = _x1 ,j1 = 1;
             //
            _x2 = node[i].x - node[i].z ;
            if(_x2 >= 0 && _x2 <= L)
            {
                tmp[++tot] = _x2 ;
                j2 = 1 ;
            }
            //
            _x3 = node[i].x + node[i].y ;
            if(_x3 >= 0 && _x3 <= L)
            {
                tmp[++tot] = _x3 ;
                j3 = 1;
            }
            if( j1 && j2 && j3)
             mp1[node[i].x] =  _x3 ,
                mp2[node[i].x] = _x2 ,
                jump[node[i].x] = 1;
        }
        sort(tmp + 1, tmp + tot + 1) ;
        int p = 1;
        point[p] = tmp[1] ;
        for(int i = 2;i <= tot ; ++i)
        if(tmp[i] != point[p])
            point[++p] = tmp[i] ;
        for(int i = 1; i<= p ;++i)
        mp[point[i]] = i;
        //
        for(int i =1; i<= p ; ++ i)
        printf("%d ",point[i]) ;cout<//
        clr1(dp) ;
        dp[1] = point[1] ;
        int res = dp[1] -point[1] ;
        if(jump[point[1]])
        {
            int t = mp[ mp1[point[1] ]] ;
            int t2 = mp[mp2[point[1]]] ;
            dp[t] = min(dp[t] , dp[t2] + point[1] - mp2[point[1]]) ;
        }
        for(int i = 1; i <= p ; ++i )
        {
            dp[i] = min(dp[i] , point[i] + res ) ;
            dp[i] = min(dp[i] , point[i] ) ;
            if(jump[point[i]])
            {
                int t = mp[ mp1[point[i] ]] ;
                int t2 = mp[mp2[point[i]]] ;
                dp[t] = min(dp[t] , dp[t2] + point[i] - mp2[point[i]]) ;
            }
            res = min(res , dp[i] - point[i] ) ;

        }
        for(int i =1; i<= p ; ++i)
        printf("%d ",dp[i]);cout<int ans = INF ;
        for(int i = 1;i <= p ; ++ i)
            ans = min(ans , L - point[i] + dp[i]);
        cout<

感觉题目还是做的太少了啊 ,还是太弱了,很多题其实都是可以写出来的,但是现场有时候是没勇气,有时候方向没想对,总的来说还是太vegetable了

你可能感兴趣的:(赛后总结)