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; }
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; }
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; }
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; //}
J: