那些年错过的蓝桥杯(三)

               **第六届蓝桥杯A组省赛**

饮料换购
乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。

请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的n瓶饮料,最后他一共能喝到多少瓶饮料。

输入:一个整数n,表示开始购买的饮料数量(0 < n < 10000)
输出:一个整数,表示实际得到的饮料数

例如:
用户输入:
100
程序应该输出:
149

用户输入:
101
程序应该输出:
151

#include 
using namespace std;

int main()
{
    ifstream infile("in.txt");
    int s,n;
    infile>>n;
    s=n;
    while (n>=3) {
        s+=n/3;
        n=n/3+n%3;
    }
    cout<return 0;
}

垒骰子
赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。
经过长期观察,atm发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。
假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。
atm想计算一下有多少种不同的可能的垒骰子方式。
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
由于方案数可能过多,请输出模 10^9 + 7 的结果。
不要小看了 atm 的骰子数量哦~

「输入格式」
第一行两个整数 n m
n表示骰子数目
接下来 m 行,每行两个整数 a b ,表示 a 和 b 数字不能紧贴在一起。

「输出格式」
一行一个数,表示答案模 10^9 + 7 的结果。

「样例输入」
2 1
1 2

「样例输出」
544

「数据范围」
对于 30% 的数据:n <= 5
对于 60% 的数据:n <= 100
对于 100% 的数据:0 < n <= 10^9, m <= 36

#include 
using namespace std;
typedef long long ll;
const int MO=1e9+7;
const int opps[]={0,4,5,6,1,2,3};
struct Mat {
    int r,c;
    ll el[7][7];
    Mat() {}
    Mat(ll x) {
        r=c=6;
        memset(el,0,sizeof(el));
        for (int i=1;i<=r;i++)  el[i][i]=x;
    }
    Mat(int _r,int _c,ll x){
        r=_r;c=_c;
        for (int i=1;i<=r;i++) 
            for (int j=1;j<=c;j++)  el[i][j]=x;
    }
    Mat operator *(const Mat &b) {
        Mat res(r,b.c,0);
        for (int i=1;i<=r;i++) 
            for (int j=1;j<=b.c;j++) 
                for (int k=1;k<=c;k++) res.el[i][j]+=el[i][k]*b.el[k][j];
        return res;
    }
    Mat operator %(const int Mo) {
        for (int i=1;i<=r;i++) 
            for (int j=1;j<=c;j++) 
                el[i][j]=el[i][j]%Mo;
        return (*this);
    }
};
template <class DataType>
DataType fpow(DataType x,int n){
    DataType res(1);
    while (n) {
        if (n&1)  res=x*res%MO;
        x=x*x%MO;
        n>>=1;
    }
    return res;
}
int main()
{
    ifstream infile("in.txt");
    int n,m;
    infile>>n>>m;
    Mat coop(6,6,1);
    for (int i=1;i<=m;i++) {
        int x,y;
        infile>>x>>y;
        coop.el[x][opps[y]]=0;
        coop.el[y][opps[x]]=0;
    }
    coop=fpow(coop,n-1);
    ll ans=0,fo=4;  
    for (int i=1;i<=6;i++)
        for(int k=1;k<=6;k++) ans=(ans+coop.el[i][k])%MO;
    ans=ans*fpow(fo,n)%MO;
    cout<return 0;
}

灾后重建
Pear市一共有N(<=50000)个居民点,居民点之间有M(<=200000)条双向道路相连。这些居民点两两之间都可以通过双向道路到达。这种情况一直持续到最近,一次严重的地震毁坏了全部M条道路。
震后,Pear打算修复其中一些道路,修理第i条道路需要Pi的时间。不过,Pear并不打算让全部的点连通,而是选择一些标号特殊的点让他们连通。
Pear有Q(<=50000)次询问,每次询问,他会选择所有编号在[l,r]之间,并且 编号 mod K = C 的点,修理一些路使得它们连通。由于所有道路的修理可以同时开工,所以完成修理的时间取决于花费时间最长的一条路,即涉及到的道路中Pi的最大值。

你能帮助Pear计算出每次询问时需要花费的最少时间么?这里询问是独立的,也就是上一个询问里的修理计划并没有付诸行动。

【输入格式】
第一行三个正整数N、M、Q,含义如题面所述。
接下来M行,每行三个正整数Xi、Yi、Pi,表示一条连接Xi和Yi的双向道路,修复需要Pi的时间。可能有自环,可能有重边。1<=Pi<=1000000。
接下来Q行,每行四个正整数Li、Ri、Ki、Ci,表示这次询问的点是[Li,Ri]区间中所有编号Mod Ki=Ci的点。保证参与询问的点至少有两个。

【输出格式】
输出Q行,每行一个正整数表示对应询问的答案。

【样例输入】
7 10 4
1 3 10
2 6 9
4 1 5
3 7 4
3 6 9
1 5 8
2 7 4
3 2 10
1 7 6
7 6 9
1 7 1 0
1 7 3 1
2 5 1 0
3 7 2 1

【样例输出】
9
6
8
8

【数据范围】
对于20%的数据,N,M,Q<=30
对于40%的数据,N,M,Q<=2000
对于100%的数据,N<=50000,M<=2*10^5,Q<=50000. Pi<=10^6.
Li,Ri,Ki均在[1,N]范围内,Ci在[0,对应询问的Ki)范围内。

#include 
#define M 200001
#define N 50001
using namespace std;
struct Node{
    int b1,e1,value;
};
struct Pan{
    int max,a,b;
    Pan *pa,*pb;
};
set<int> my[2*M];
Pan *pp[N],*head;
priority_queue t;
int mark[N],sig[N];
int n,m,q,sum=0;
bool operator<(Node a,Node b){
    return a.value>b.value;
}
ostream& operator<<(ostream &out,Node &a){
    out<" "
       <" "
       <return out;
}
int find(int x,int m[]){
    if(x==m[x]) return x;
    else return find(m[x],m);
}
void unio(int x,int y,int m[]){
    int a,b;
    a=find(x,m);
    b=find(y,m);
    if(a!=b) m[a]=b;
}
bool check(Node te){
     int a=find(te.b1,sig);
     int b=find(te.e1,sig);
     if(a==b) return false;
     unio(a,b,sig);
     return true;
}
void he(int x){
     if(pp[x]!=NULL) {
        int at=pp[x]->a;
        set<int>::iterator it;
        for(it=my[at].begin();it!=my[at].end();it++)
            my[sum].insert(*it);
        at=pp[x]->b;
        for(it=my[at].begin();it!=my[at].end();it++)
            my[sum].insert(*it);
     }
}
void ptree(Node te){
     int a=find(te.b1,mark);
     int b=find(te.e1,mark);
     Pan *p=(Pan *)malloc(sizeof(Pan));
     p->max=te.value;
     my[sum].insert(te.b1);
     he(a);
     p->a=sum;
     p->pa=pp[a];
     my[++sum].insert(te.e1);
     he(b);
     p->b=sum++;
     p->pb=pp[b];
     unio(a,b,mark);
     pp[b]=p;
     head=p;
     //cout<a<<"  "<b<<"********\n";
}
void print(Pan *p){
     if(p==NULL) return;
     cout<max<set<int>::iterator it;
     cout<<"left: ";
     for(it=my[p->a].begin();it!=my[p->a].end();it++)
         cout<<(*it)<<" ";
     cout<<"\nright: ";
     for(it=my[p->b].begin();it!=my[p->b].end();it++)
         cout<<(*it)<<" ";   
     cout<pa);
     print(p->pb);
}
int refer(set<int> gg,Pan *p){
    set<int>::iterator it;
    int t1=0,t2=0;
    for(it=gg.begin();it!=gg.end();it++){
        if(my[p->a].find(*it)!=my[p->a].end()) t2++;
        t1++;
        if(t1!=t2&&t2!=0) break;
    }
    if(t1==t2) return refer(gg,p->pa);
    if(t2==0)  return refer(gg,p->pb);
    return p->max;
}
int main(int argc, char *argv[]) {
    ifstream infile("in.txt");
    int tot=0,a,b,c,d;
    struct Node bri;
    infile>>n>>m>>q;
    for(int i=1;i<=n;i++) {
        sig[i]=i;
        mark[i]=i;
    }
    for(int i=0;i>bri.b1>>bri.e1>>bri.value;
        t.push(bri);
    }
    while(!t.empty()){
        bri=t.top();
        t.pop();
        bool bb=check(bri);
        if(bb==false) continue;
        tot++;
        ptree(bri);
        if(tot==m-1) break;
    }
    //cout<<"tree ok\n";
    //print(head);
    for(int i=0;i>a>>b>>c>>d;
        int k;
        for(k=a;k<=b;k++)
            if(k%c==d) break;
        set<int> cc;
        for(int g=k;g<=b;g+=c)
           cc.insert(g);
        cout<return 0;
}

那些年错过的蓝桥杯(三)_第1张图片

坑了宝宝这么久,终于有结果了.
[email protected]

你可能感兴趣的:(计算机语言)