关于最近做的一些题的归档吧

第一套题

1 CFGym 101853G Hard Equation

BSGS 算法的模板题 (题目中给的那个最后一个样例结果也可以是0)
[关于bsgs算法学习的链接1](http://blog.miskcoo.com/2015/05/discrete-logarithm-problem) 
[关于bsgs算法学习的链接2](https://blog.csdn.net/lycheng1215/article/details/79047734) 
[关于bsgs算法学习的链接3](https://ksmeow.moe/baby_step_giant_step/) 

第二套题 (The 18th Zhejiang University Programming Contest Sponsored)

1 F-Schrödinger’s Knapsack

准确的来说这道题是一道背包,但是它的价值会变,当时就做成sb了淦
容易猜出来无论先装啥都要先装背包占比小的 所以排序 
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
ll a, b, c, t, i, j, ans, n1, val, n2, q[2005], w[2005], dp[2005][2005];
ll s[2005][2005];
int main()
{
    while (~scanf("%lld", &t))
    {
        while (t--)
        {
            scanf("%lld%lld%lld", &a, &b, &val);
            scanf("%lld%lld", &n1, &n2);
            for (i = 0; i < n1; i++)
            {
                scanf("%lld", &q[i]);
            }
            for (i = 0; i < n2; i++)
            {
                scanf("%lld", &w[i]);
            }
            for(i=0;i<=n1;i++)
                for(j=0;j<=n2;j++)
                    s[i][j]=dp[i][j]=0;
            sort(q, q + n1);
            sort(w, w + n2);
            for (i = 0; i <= n1; i++)
            {
                if (i == 0)
                    s[0][0] = val;
                else
                    s[i][0] = s[i - 1][0] - q[i - 1];
                if (s[i][0] <= 0)
                    break;
                for (j = 1; j <= n2; j++)
                {
                    s[i][j] = s[i][j - 1] - w[j - 1];
                    if (s[i][j] <= 0)
                        break;
                }
            }
            ans = 0;
            for (i = 0; i <= n1; i++)
            {
                for (j = 0; j <= n2; j++)
                {
                    if (s[i][j] <= 0)
                        break;
                    if (i > 0)
                    {
                        dp[i][j] = max(dp[i][j], dp[i - 1][j] + s[i][j] * a);
                    }
                    if (j > 0)
                    {
                        dp[i][j] = max(dp[i][j], dp[i][j - 1] + s[i][j] * b);
                    }
                    ans = max(ans, dp[i][j]);
                }
            }
            printf("%lld\n", ans);
        }
    }
    return 0;
}

G-Pretty Matrix

着个题是一个广搜,太菜了想不通问队友就简单搜索标记搞就完事了…
注意 这题是n*m<1e5 所以等输入后再开辟数组 (vector好像也行队友用的vector 但是我试的好像不行 不知道是不是我的问题)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
struct qwe
{
    int a, b;
    int flag;
    bool operator<(const qwe &a1) const
    {
        if (a == a1.a && b == a1.b)
            return flag < a1.flag;
        if (a == a1.a)
            return b < a1.b;
        return a < a1.a;
    }
};
struct qwe1
{
    int a, b;
    int val;
};
int t, n, m, ans, a, b, c, d;
int solve(int n,int m)
{
    int v[n+1][m+1];
    int i, j, d;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            scanf("%d", &v[i][j]);
        }
    }
    scanf("%d%d%d%d", &a, &b, &c, &d);
    int flag, d1;
    queue<qwe1> q1;
    map<qwe, int> m1;
    struct qwe1 a1;
    struct qwe b1;
    a1.a = a;
    a1.b = b;
    a1.val = 0;
    q1.push(a1);
    while (!q1.empty())
    {
        a1 = q1.front();
        q1.pop();
        d1 = a1.val;
        b1.a = a1.a;
        b1.b = a1.b;
        flag = (v[a1.a - 1][a1.b - 1] + d1) % 2;
        b1.flag = flag;
        //cout<<a1.a<<" "<<a1.b<<endl;
        //cout<<m1.count(b1)<<" "<<q1.size()<<endl;
        if (m1.count(b1) != 0)
            continue;
        if (a1.a == c && a1.b == d)
            return a1.val;
        m1[b1] = 1;
        if (flag)
        {
            struct qwe1 tmp;
            tmp = a1;
            tmp.val = a1.val + 1;
            if (a1.b + 1 <= m)
            {
                tmp.b = a1.b + 1;
                q1.push(tmp);
            }
            if (a1.b - 1 > 0)
            {
                tmp.b = a1.b - 1;
                q1.push(tmp);
            }
        }
        else
        {
            struct qwe1 tmp;
            tmp = a1;
            tmp.val = a1.val + 1;
            if (a1.a + 1 <= n)
            {
                tmp.a = a1.a + 1;
                q1.push(tmp);
            }
            if (a1.a - 1 > 0)
            {
                tmp.a = a1.a - 1;
                q1.push(tmp);
            }
        }
    }
    return -1;
}
int main()
{
    while (~scanf("%d", &t))
    {
        while (t--)
        {
            scanf("%d%d", &n, &m);
            ans=solve(n,m);
            printf("%d\n",ans);
        }
    }
    return 0;
}

第三套(The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored)

E - LIS

贪心就完事了 gtmd 还是太菜了不会

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#define mod 1000000000
using namespace std;
typedef long long LL;
struct qwe {
    LL num,i;
    LL r,l;
    LL first;
}q[100005];
int cmp(struct qwe a,struct qwe b)
{
    if(a.i==b.i)
        return a.num>b.num;
    return a.i<b.i;
}
LL ans[100005],next1[100005],n,i,j,L,t;
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld",&n);
        memset(ans,0,sizeof(ans));
        for(i=0;i<n;i++)
        {
            scanf("%lld",&q[i].i);
            q[i].num=i;
            q[i].first=next1[q[i].i-1];
            next1[q[i].i]=i;
        }
        for(i=0;i<n;i++)
        {
            scanf("%lld%lld",&q[i].l,&q[i].r);
        }
        sort(q,q+n,cmp);
        L=0;
        for(i=0;i<n;i++)
        {
            //cout<<ans[q[i].first]<<"  ";
            if(i==0)
                ans[q[i].num]=L=q[i].l;
            else
            {
                if(q[i].i!=q[i-1].i)
                {
                    L=ans[q[i].first]+1;
                    //cout<<q[i].num<<" "<<q[i].i<<" "<<q[i].l<<" "<<q[i].r<<" "<<L<<endl;
                    ans[q[i].num]=L=max(q[i].l,L);
                }
                else
                {
                    //cout<<q[i].num<<" "<<q[i].i<<" "<<q[i].l<<" "<<q[i].r<<" "<<L<<" "<<ans[q[i].first]+1<<endl;
                    ans[q[i].num]=L=max(L,max(q[i].l,ans[q[i].first]+1));
                }
            }
            //cout<<ans[q[i].num]<<endl;
        }
        printf("%lld",ans[0]);
        for(i=1;i<n;i++)
        {
            printf(" %lld",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

F-Now Loading!!!

玛格级 想出这题的人都不是一般人 我是真想不出来 因为题给的数据范围太大就现将结果打表在后面输入查询的时候直接二分查表就行了 哔~哔~哔~(因不明原因屏蔽)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#define mod 1000000000
using namespace std;
typedef long long LL;

LL t, i, j, n, ans, dd, dd1, dd2, a, b;
LL q[500050];
LL w, ans1, l, r, mid;
LL sum[32][500050];
int main()
{
    scanf("%lld", &t);
    while (t--)
    {
        scanf("%lld%lld", &a, &b);
        for (i = 1; i <= a; i++)
            scanf("%lld", &q[i]);
        sort(q + 1, q + a + 1);
        for (j = 1; j <= 30; j++)
            for (i = 1; i <= a; i++)
            {
                sum[j][i] = sum[j][i-1] + q[i] / j;
            }
        ans = 0;
        for (j = 1; j <= b; j++)
        {
            scanf("%lld", &w);
            dd = 1;//k
            ans1 = 0;//temp
            dd1 = 0;//pos
            dd2 = w;//up
            for (i = 1; i <= a; i = dd1 + 1)
            {
                dd1 = i - 1;
                l = i;
                r = a;
                while (l <= r)
                {
                    mid = (l + r) >> 1;
                    if (q[mid] <= dd2)
                    {
                        dd1 = mid;
                        l = mid + 1;
                    }
                    else
                    {
                        r = mid - 1;
                    }
                }
                ans1 = (ans1 + sum[dd][dd1] - sum[dd][i-1] + mod) % mod;
                dd++;
                dd2 *= w;
            }
            ans = (ans + ans1 * j) % mod;
        }
        printf("%lld\n", (ans + mod) % mod);
    }
    return 0;
}

I-Magic Points

题意是对n*n的正方形取边上的点 连线不能平行x和y轴 问前 n条边连线交点最多的 就i和i+n就完事了 但是 最后一个点 会和之前的点有重复 所以 最后一点 要重新找

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
int t,i,j,n;
int main()
{
    while (~scanf("%d", &t))
    {
        while(t--)
        {
            scanf("%d",&n);
            if(n==2)
                printf("0 2 1 3");
            else
            {
                for(i=0;i<n-1;i++)
                {
                    printf("%d %d ",i,i+n);
                }
                printf("%lld %lld",n-1,3*n-4);
            }
            printf("\n");
        }
    }
    return 0;
}

第四套

F - Never Wait for Weights

这题是个并查集 比赛 时候想到了 但是 犯蠢 减错了权值 ( 还是太菜 学不来

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#define eps 0.0000000001
#define mem(a) memset(a,0,sizeof(a))
#define maxx 1e10
#define inf 0x3f3f3f3f
#define PI acos(-1)
#define show(a) cout<<a<<endl
//#define show(a,b) cout<<a<<" "<<b<<endl
using namespace std;
typedef long long ll;
ll father[100005],val1[100005];
ll Find(ll x)
{
    ll t=x,d=x,sum=0,sum1;
    while(x!=father[x])
    {
        sum+=val1[x];
        x=father[x];
    }
    sum+=val1[x];
    //cout<<"***"<<sum<<endl;
    while(x!=t)
    {
        d=father[t];
        father[t]=x;
        sum1=val1[t];
        val1[t]=sum;
        t=d;
        sum=sum-sum1;
    }
    return x;
}
void Union(ll x,ll y,ll v)
{
    ll fx=Find(x);
    ll fy=Find(y);
    if(fx!=fy)
    {
        father[fx]=fy;
        val1[fx]=v+val1[y]-val1[x];
    }
}
ll n,m,val,i,j,a,b,ans;
char q[20];
int main()
{
    while(~scanf("%lld%lld",&n,&m))
    {
        if(n==0&&m==0)
            break;
        for(i=1;i<=n;i++)
            father[i]=i;
        memset(val1,0,sizeof(val1));
        for(i=0;i<m;i++)
        {
            scanf(" %s",q);
            if(q[0]=='!')
            {
                scanf("%lld%lld%lld",&a,&b,&val);
                Union(a,b,val);
            }
            else
            {
                scanf("%lld%lld",&a,&b);
                if(Find(a)!=Find(b))
                {
                    printf("UNKNOWN\n");
                }
                else
                {
                    ans=val1[b]-val1[a];
                    printf("%lld\n",-ans);
                }
            }
        }
    }
}

第五套

没补

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值