SICNU 2018 Summer Training #11
A题,签到A Math Problem
给你一个数n,问有多少个k,满足k^k<=n
用快速幂求出k从1到15的幂次,然后每次查询的时候遍历就行了
#include <cstdio> #include <iostream> #include <string> #include <algorithm> #include <cstring> #include <cmath> #include <map> #include <stack> #define INF 1e9 using namespace std; unsigned long long power_mod(long long a, long long b) { long long ans = 1; while (b) { if (b & 1) ans = ans * a; a = a * a; b >>= 1; } return ans; } int main() { int m=0; long long n; unsigned long long num[100]; for(int i=1;i<=16;i++) num[i]=power_mod(i,i); while(~scanf("%lld",&n)){ m=0; for(int i=1;i<=15;i++){ if(n>=num[i]) m++; else break; } printf("%d\n",m); } return 0; }
E题,CS Course第一眼看上去比较简单,但是思路挺难想的
首先给一串序列,然后给一些查询,每次查询的内容是除去序列中被查询序号的数,之后的与,或,和异或
思路:首先异或是很简单的,因为异或是有逆运算的,就是他自己(即a^b=c < = > a=b^c),但是与和或没有,一开始以为与和或互为逆运算,然后推了一下,wa了,后面想到了用前缀和后缀数组,就可以避开这个数,去求与和或
#include <cstdio> #include <iostream> #include <string> #include <algorithm> #include <cstring> #include <cmath> #include <map> #include <stack> #define INF 1e9 using namespace std; int sw[100005]; long long a[100005],b[100005],c=0; long long a1[100005],b1[100005]; int main() { int n,m; int t; while(~scanf("%d %d",&n,&m)){ scanf("%d",&sw[1]); a[1]=sw[1]; b[1]=sw[1]; c=a[1]; for(int i=2;i<=n;i++){ scanf("%d",&sw[i]); a[i]=a[i-1]&sw[i]; b[i]=b[i-1]|sw[i]; c^=sw[i]; } a1[n]=sw[n]; b1[n]=sw[n]; for(int i=n-1;i>=1;i--){ a1[i]=a1[i+1]&sw[i]; b1[i]=b1[i+1]|sw[i]; } for(int i=0;i<m;i++){ scanf("%d",&t); if(t==1) printf("%lld %lld %lld\n",a1[2],b1[2],c^sw[t]); else if(t==n) printf("%lld %lld %lld\n",a[n-1],b[n-1],c^sw[t]); else { long long q,w; q=a[t-1]&a1[t+1]; w=b[t-1]|b1[t+1]; printf("%lld %lld %lld\n",q,w,c^sw[t]); } } } return 0; }
然后是G题,对子和顺子。
首先给了两个定义,两个相同的数可以构成对子,而三个连续的数构成顺子
给一串序列,问顺子和对子最多有多少个
思路,就按顺序先把对子确定,然后把顺子确定
#include <iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<map> using namespace std; int a[1000001]; int main() { int n,i,x; while(~scanf("%d",&n)) { memset(a,0,sizeof(a)); for(i=1;i<=n;i++) { scanf("%d",&x); a[x]++; } int ans=0; for(i=1;i<=n;i++) { ans+=a[i]/2; a[i]=a[i]%2; if(a[i]&&a[i+1]%2&&a[i+2]) { ans++; a[i]--; a[i+1]--; a[i+2]--; } } printf("%d\n",ans); } return 0; }