牛客网多校第三场

A:

四维的01背包,注意一下所有代价都是0时的方案输出即可

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

#define maxn 37

using namespace std;

int p[maxn],a[maxn],c[maxn],m[maxn],g[maxn];
int dp[maxn][maxn][maxn][maxn],use[maxn];
int n,P,A,C,M;

vector <int> mem;

int main(){
    scanf("%d",&n);
    int cnt=0;

    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d%d%d",&p[i],&a[i],&c[i],&m[i],&g[i]);
        if(p[i]==0&&a[i]==0&&c[i]==0&&m[i]==0)
        {
            mem.push_back(i);
            use[i]=1;
        }
    }
    scanf("%d%d%d%d",&P,&A,&C,&M);
    dp[0][0][0][0]=0;
    for(int i=1;i<=n;i++){
        if(use[i]==1) continue;
        for(int j=P;j>=0;j--)
            for(int k=A;k>=0;k--)
                for(int t=C;t>=0;t--)
                    for(int l=M;l>=0;l--)
                        if(j>=p[i] && k>=a[i] && t>=c[i] && l>=m[i]){
                            if(dp[j][k][t][l]<dp[j-p[i]][k-a[i]][t-c[i]][l-m[i]]+g[i]){
                                dp[j][k][t][l]=dp[j-p[i]][k-a[i]][t-c[i]][l-m[i]]+g[i];
                            }
                        }
    }
    int ans=0,l1=P,l2=A,l3=C,l4=M;
    for(int j=P;j>=0;j--)
            for(int k=A;k>=0;k--)
                for(int t=C;t>=0;t--)
                    for(int l=M;l>=0;l--)
                        if(dp[j][k][t][l]>=ans){
                            l1=j; l2=k; l3=t; l4=l;
                            ans=dp[j][k][t][l];
                        }

    while(1){
        int t=233;
        for(int i=1;i<=n;i++)
            if(!(p[i]==0 && a[i]==0 && c[i]==0 && m[i]==0) && !use[i] && l1>=p[i] && l2>=a[i] && l3>=c[i] && l4>=m[i] && dp[l1][l2][l3][l4]==dp[l1-p[i]][l2-a[i]][l3-c[i]][l4-m[i]]+g[i]){
                use[i]=1; t=i; break;
            }
        if(t==233) break;
        mem.push_back(t);
        l1-=p[t]; l2-=a[t]; l3-=c[t]; l4-=m[t];
    }
    printf("%d\n",mem.size());
    for(int i=0;i<mem.size();i++)
        printf("%d ",mem[i]-1);
    return 0;
}
View Code

C:

E:

先把串拼成二倍长,预处理整串hash值。然后遍历取n个字符的hash值,map一下看看有没有重复并且存到vector中,最后直接输出

然鹅被卡常了还是getchar快一点

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#define LSON l,m,x<<1
#define RSON m+1,r,x<<1|1
using namespace std;

const int MAX=2e6+5;
const unsigned long long base = 163;
char s[MAX];
unsigned long long p[MAX],hh[MAX];
unordered_map<unsigned long long,int> mp;
int cnt;
vector<int> L[MAX];

void init(){//处理hh值
    p[0] = 1;
    hh[0] = 0;
    int n = strlen(s + 1);
    for(int i = 1; i < MAX/2; i ++) p[i] =p[i-1] * base;
    for(int i = 1; i <= n; i ++) hh[i] = hh[i - 1] * base + (s[i] - 'a');
}

inline unsigned long long get(int l, int r){//取出g里l - r里面的字符串的hh值
    return hh[r] - hh[l - 1] * p[r - l + 1];
}

inline string read()//inline继续加快速度
{
    char ch=getchar();
    string st1="";
    while (!((ch>='a')&&(ch<='z')))//把前面没用的东西去掉,当然,ch在什么范围内可以依据需要修改
      ch=getchar();
    while ((ch>='a')&&(ch<='z'))
      st1+=ch,ch=getchar();
    return st1;//返回
}//在主程序内可以写st=read(),这样子要读的字符串就到了st内

int main(){
    int i,j; char ch;
    i=0;
    while((ch=getchar())!=EOF){
        s[++i]=ch;
    }
    if(s[i]=='\n') i--;
    int n=i;
    for(i=n+1;i<=2*n;i++)
        s[i]=s[i-n];
    init();
    for(i=1;i<=n;i++){
        unsigned long long h=get(i,i+n-1);
        if(!mp[h]){
            mp[h]=++cnt;
            L[cnt].push_back(i-1);
        }
        else
            L[mp[h]].push_back(i-1);
    }
    printf("%d\n",cnt);
    for(i=1;i<=cnt;i++){
        int size=L[i].size();
        printf("%d ",size);
        for(j=0;j<size;j++){
            printf("%d%c",L[i][j],j==size-1?'\n':' ');
        }
    }
    return 0;
}
View Code

H:

随便推推公式就好,发现和小于n/num的质数数量有关,求一求质数数量的前缀和

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <map>
using namespace std;

int pri[6000010], cnt;
bool flag[10000010];
long long sum[10000010];

void init()
{
    cnt=0;
    for(int i = 2; i <= 10000000; i ++)
    {
        if(!flag[i])
        {
            pri[cnt ++] = i;
            flag[i] = 1;
        }
        for(int j = 0; j < cnt && i * pri[j] <= 10000000; j ++)
        {
            flag[i * pri[j]] = 1;
            if(i % pri[j] == 0)
            {
                break;
            }
        }
    }
}

int main()
{
    int i;
    init();
    for(i=0;i<cnt;i++) sum[pri[i]]++;
    for(i=0;i<=10000000;i++) sum[i]+=sum[i-1];
    int n;
    scanf("%d",&n);
    long long ans=0;
    for(i=1;i<=n;i++)
    {
        ans+=sum[n/i]*(sum[n/i]-1);
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

I:

扫描二维码关注公众号,回复: 2392445 查看本文章

本地模拟打表

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <string>
#include <map>
#include <ctime>
#define LSON l,m,x<<1
#define RSON m+1,r,x<<1|1
#define RAND_MAX 80000
using namespace std;

const int MAX=30000+5;

//1.1 Point定义 
const double eps=1e-8; 
const double PI=acos(-1.0); 
int sgn(double x) 
{
    if(fabs(x)<eps)return 0;
    if(x < 0)return -1;
    else return 1;
}
struct Point
{
    double x,y;
    Point(){}                                    //默认构造器(),如果没有自定义构造器,则编译器会自动生成默认构造器 
    Point(double _x,double _y)    //自定义构造器 
    {
        x=_x;y=_y;
    }
    /*
        Point(double _x,double _y) : x(_x), y(_y)    //自定义构造器版本2,效果同上,但效率更高 
    {
    }
    */
    Point operator - (const Point &b)const
    {
        return Point(x-b.x,y-b.y); 
    }
    double operator ^ (const Point &b)const//叉积
    {
        return x*b.y-y*b.x;
    }
    double operator * (const Point &b)const//点积
    {
        return x*b.x+y*b.y;
    }
    bool operator < (const Point &b)const
    {
        if(x==b.x) return y<b.y;
        return x<b.x;
    }
    void transXY(double B)//绕原点旋转角度B(弧度值),后x,y的变化 
    {
        double tx=x,ty=y;
        x=tx*cos(B)-ty*sin(B);
        y=tx*sin(B)+ty*cos(B);
    }
};

//输入点数组p,个数为n,输出点数组ch。返回凸包顶点数
//输入不能有重复点。函数执行完之后输入点的顺序被破坏
//如果不希望在凸包的边上有输入点,把两个<=改为<
//在精度要求高时建议用cmp比较

int ConvexHull(Point* p,int n,Point *ch)
{
    sort(p,p+n); //先比较x坐标,再比较y坐标
    int m=0;
    for(int i=0;i<n;i++)
    {
        while(m > 1 && ((ch[m-1]-ch[m-2])^(p[i]-ch[m-2])) <= 0) m--;
        ch[m++] = p[i];
    }
    int k = m;
    for(int i = n-2; i >= 0; i--)
    {
        while(m > k && ((ch[m-1]-ch[m-2])^(p[i]-ch[m-2])) <= 0) m--;
        ch[m++] = p[i];
    }
    if(n > 1) m--;
    return m;
}

int m=1e7,n;
Point p[MAX],ch[MAX];
double ans;
long long sum;

int Rand(int l,int r){
    return (((long long)rand())*rand()%(r-l+1)+l);
}

int main(){
    int i,j;
    
    srand(time(0));
    printf("%d\n",RAND_MAX);
    for(n=4;n<=10;n++){
        sum=0;
        for(j=0;j<m;j++){
            //cout<<j<<endl;
            for(i=0;i<n;i++){
                p[i].x=rand();
                p[i].y=rand();
                if(p[i].x>p[i].y) swap(p[i].x,p[i].y);
            }
            sum+=ConvexHull(p,n,ch);
        }
        printf("%lf,",(double)sum/m);
    }
    
    return 0;
}

//double ans[100]={0,0,0,3.000000,3.000000,4.000000,4.000000,5.000000,6.000000,6.000000,6.000000};

//int main(){
//    int n;
//    int a,b,c,x,y,z;
//    scanf("%d%d%d%d%d%d%d",&a,&b,&c,&x,&y,&z,&n);
//    printf("%lf\n",ans[n]);
//    
//    return 0;
//}
View Code

J:

猜你喜欢

转载自www.cnblogs.com/Hetui/p/9374383.html