1001
找出第一个 2a3b5c7d (a,b,c,否是非负整数) 大于等于n的数
莫名其妙打表过、
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef __int64 ll;
ll num[100000];
ll quick(ll a, ll b){
ll res=1;
while(b){
if(b&1) res*=a;
a=a*a;
b>>=1;
}
return res;
}
int Get(ll a, ll b){
if(a>1e9&&b>1e9) return 20;
int ans=0,res=0;
int c=a*b;
while(a){
a/=10;
res++;
}
while(b){
b/=10;
res++;
}
while(c){
c/=10;
ans++;
}
return min(ans, res);
}
int main(){
//printf("%I64d\n", quick(3, 19));
//printf("%I64d\n", quick(5, 13));
//printf("%I64d\n", quick(7, 11));
num[0]=1;
int count=1;
for(ll i,j,k,l=0; l<31; ++l)
for(k=0; k<19; ++k)
for(j=0; j<13; ++j)
for(i=0; i<11; ++i){
ll a=quick(2, l);
ll b=quick(3, k);
ll c=quick(5, j);
ll d=quick(7, i);
if(Get(a, b)+Get(c, d)>=14) break;
num[count++]=a*b*c*d;
}
//printf("%d\n", count);
sort(num, num+count);
int t;scanf("%d",&t);
while(t--){
int n;scanf("%d",&n);
printf("%I64d\n", num[lower_bound(num, num+count, n)-num]);
}
return 0;
}
1002
求 1/(k*k) k从1到n的和、 看清题目只要求保留5位小数,所以打表到1e6才够了、少一点好像不行、 因为后面叠加的数值还是会加上来、所以尽可能开的一点
#include<stdio.h>
#include<cstring>
double num[1000000+2];
char s[1000000];
int main(){
num[1] = 1.0;
for(long long i=2; i<=1e6; ++i)
num[i]=num[i-1]+1.0/(i*i);
int n;
while(scanf("%s",s)!=EOF){
if(strlen(s)>6) {
printf("%.5lf\n", num[1000000]);
continue;
}
int ans=0;
for(int i=0; i<strlen(s); ++i)
ans=ans*10+s[i]-'0';
printf("%.5lf\n", num[ans]);
}
return 0;
}
1006
题意:nnn
个点mmm
条无向边的图,找一个欧拉通路/回路P0,P1,..PmP_0, P_1, .. P_mP0,P1,..Pm
(PiP_iPi
是节点标号),使得aP0⊕aP1⊕..⊕aPma_{P_0} \oplus a_{P_1} \oplus .. \oplus a_{P_m}aP0⊕aP1⊕..⊕aPm
最大。输出这个值。
题解:由欧拉路性质,奇度点数量为0或2。一个节点被进一次出一次,度减2,产生一次贡献,因此节点uuu
的贡献为(⌊degreeu2⌋ mod 2)∗au(\lfloor \frac {degree_u}{2} \rfloor\text{ mod }2) * a_u(⌊2degreeu⌋ mod 2)∗au
。欧拉回路的起点贡献多一次,欧拉通路的起点和终点贡献也多一次。因此如果是欧拉回路的话枚举一下起点就好了。
<span style="color:#000000;">#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef __int64 ll;
const int qq = 1e5+10;
int w[qq];
int vis[qq];
int pre[qq];
int find(int x){
return x==pre[x]?x:pre[x]=find(pre[x]);
}
int main(){
int t;scanf("%d",&t);
while(t--){
int n,m;scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i) scanf("%d", w+i);
int a,b;
for(int i=0; i<m; ++i){
scanf("%d%d",&a,&b);
vis[a]++,vis[b]++;
}
int k=0;
for(int i=1; i<=n; ++i) if(vis[i]%2==1) k++;
if(k==0||k==2){
int res=0;
for(int i=1; i<=n; ++i)
if(vis[i]!=0) res^=((vis[i]+1)/2%2)*w[i]; //加1保证奇度顶点产生的贡献计算正确,对偶度顶点没有影响
if(k==2) printf("%d\n", res);
else{
int maxn=-1;
for(int i=1; i<=n; ++i)
maxn = max(maxn, res^w[i]);
printf("%d\n", maxn);
}
}
else printf("Impossible\n");
memset(vis, 0, sizeof(vis));
}
return 0;
}</span>
这题我比赛的时候没做出来真有点可惜的、 也尝试着去分析了奇度顶点和偶度顶点,也知道应为要遍历所有的边所以那个最大值在k=2的情况下是一个定值,就是没想到去算每一个点的贡献值... 对这类题大致也有了个了解吧、