Powered by:AB_IN 局外人
只會這些題了。。
A Race
模擬就。
#include <bits/stdc++.h>
using namespace std;
int main() {
int v1, v2, t, s, l;
cin >> v1 >> v2 >> t >> s >> l;
int s1 = 0, s2 = 0;
int time1 = 0, time2 = 0;
while (s1 < l && s2 < l) {
if (s1 - s2 >= t) {
s1 = v1 * time1;
time2 += s;
s2 = v2 * time2;
}
else {
time1++, time2++;
s1 = v1 * time1;
s2 = v2 * time2;
}
}
if (s1 < s2)
cout << "Hong " << l / v2 << endl;
else if (s1 > s2)
cout << "Ming " << time2 << endl;
else
cout << "Tie " << time2 << endl;
}
C Coronavirus
bfs板子題。
手賤一個地方寫錯了,改了將近兩小時,按着標程提交了三四十次,終於找出來了。。
#include <bits/stdc++.h>
using namespace std;
int x2[] = { 0,0,1,-1 ,1,1,-1,-1 };
int y2[] = { 1,-1,0,0 ,1,-1,1,-1 };
struct sa
{
int x;
int y;
int step;
};
queue<sa>q;
char a[55][55];
bool judge[55][55];
int n,m,xg,yg;
bool check(int x,int y)
{
if (x<0||y<0||x>n||y>m) return false;
for(int i=0;i<8;i++){
int x5=x+x2[i];
int y5=y+y2[i];
if(a[x5][y5]=='*') return false;
}
return !judge[x][y];//最後再判斷是否經過
}
int bfs(int x,int y)
{
q.push({x,y,0});
judge[x][y]=true;
while(!q.empty()){
sa tmp=q.front();
q.pop();
int x3=tmp.x;
int y3=tmp.y;
if(a[x3][y3] == 'E')
return tmp.step;
for(int i=0;i<4;i++){
int x4=x3+x2[i];
int y4=y3+y2[i];
if(check(x4,y4))
{
q.push({x4,y4,tmp.step+1});
judge[x4][y4]=true;//就是這!!!!!if裏都是x4,y4!!!!
}
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
while(cin>>n>>m){
memset(judge,0,sizeof(judge));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
if(a[i][j]=='S') {xg=i;yg=j;}
}
}
int ans=bfs(xg,yg);
if(ans==-1) cout<<"Impossible"<<endl;
else cout<<ans<<endl;
}
return 0;
}
G XOR
異或的最大值,那麼就得出1。怎麼出1呢?兩個數不同就出1。
比如給出10,它的二進制爲1010
。
那麼10以內必有一個0101
。這樣兩個數異或就是1111
,就是最大了。
需要特判一下1。
n=len(bin(int(input()))[2:]);ans=0
if n==1:
print('0')
else:
for i in range(n):
ans+=2**i
print(ans)
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
ll n,x=1;
int main()
{
cin>>n;
if(n==1)
cout<<'0'<<endl;
else{
while(x<=n) x*=2;
cout<<x-1<<endl;
}
return 0;
}
I Prime
二分做法
記一下cnt
是記錄當前素數個數。
這個使用的是prime
數組,然後二分即可,之前提到過區間問題,全是閉的話,就左區間--,右區間不變
,然後都用upper_bound
即可。
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
typedef long long ll;
const ll N=1e7+5;
ll cnt,sum,ans,prime[N],pre[N];
bool flag[N];
using namespace std;
namespace IO{
char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
inline char gc(){
if(ip!=ip_)return *ip++;
ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
return ip==ip_?EOF:*ip++;
}
inline void pc(char c){
if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
*op++=c;
}
inline ll read(){
register ll x=0,ch=gc(),w=1;
for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
return w*x;
}
template<class I>
inline void write(I x){
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);pc(x%10+'0');
}
class flusher_{
public:
~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
}IO_flusher;
}
using namespace IO;
void init()
{
memset(flag,1,sizeof(flag));
flag[1]=cnt=0;
for(ll i=2;i<=N;i++)
{
if(flag[i])
{
prime[++cnt]=i;
pre[i]=cnt;
}
for(ll j=1;j<=cnt&&prime[j]*i<=N;j++)
{
flag[prime[j]*i]=0;
if(i%prime[j]==0)break;
}
}
}
ll t,a,b;
int main()
{
init();
t=read();
while(t--){
a=read();b=read();
a--;
write(upper_bound(prime+1,prime+cnt+1,b)-upper_bound(prime+1,prime+cnt+1,a));
pc('\n');
}
}
前綴和做法
定義了一個數組v[N]
爲前綴和數組,那加什麼呢?加的是判斷數組flag[N]
。
如果是True
那麼加1,不是則不變。
看一看這個數組長啥樣:
每一個數都有值。
再對照着看看flag
:
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
typedef long long ll;
const ll N=1e7+5;
ll cnt,sum,ans,prime[N],pre[N],v[N];
bool flag[N];
using namespace std;
namespace IO{
char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
inline char gc(){
if(ip!=ip_)return *ip++;
ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
return ip==ip_?EOF:*ip++;
}
inline void pc(char c){
if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
*op++=c;
}
inline ll read(){
register ll x=0,ch=gc(),w=1;
for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
return w*x;
}
template<class I>
inline void write(I x){
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);pc(x%10+'0');
}
class flusher_{
public:
~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
}IO_flusher;
}
using namespace IO;
void init()
{
memset(flag,1,sizeof(flag));
flag[1]=cnt=0;
for(ll i=2;i<=N;i++)
{
if(flag[i])
{
prime[++cnt]=i;
pre[i]=cnt;
}
for(ll j=1;j<=cnt&&prime[j]*i<=N;j++)
{
flag[prime[j]*i]=0;
if(i%prime[j]==0)break;
}
}
}
ll t,a,b;
int main()
{
init();
t=read();
for(ll i=2;i<=N;i++)//這裏變成了N
v[i]=v[i-1]+flag[i];
while(t--){
a=read();b=read();
write(v[b]-v[a-1]);
pc('\n');
}
}
J Compare
a=int(input())
b=int(input())
if a>b:
print(">")
elif a<b:
print("<")
else:
print("=")
K Walk
逆元+組合數。
- 什麼時候用逆元?
當處理除數很大時。 - 逆元是什麼?
每個數a均有唯一的與之對應的乘法逆元x,使得 - 什麼是費馬小定理?
費馬小定理是數論中的一個重要定理。如果n是一個質數,而整數a不是n的倍數,則有 。 - 怎麼用費馬小定理推導逆元公式?
一般ACM要求的模數都是質數,所以是存在逆元的
(其實相當於1)
證畢。
- 代碼注意事項
- 因爲 要求故數組要開
2*(1e6+10)
。 - 預處理將所有的階乘都取模算好。
- 本身求最短路徑可以用做,但是這個較大,不支持用二維數組和複雜度,並且還是多組輸入,所以直接用組合數算。
- 從到 向下向右一共走步,其中向下走步,向右走步,所以 或者
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
typedef unsigned long long ull;
typedef long long ll;
const ll maxn=2*(1e6+10);
const int mod = 1e9 + 7;
ll fac[maxn],t,n,m;
using namespace std;
namespace IO{
char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
inline char gc(){
if(ip!=ip_)return *ip++;
ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
return ip==ip_?EOF:*ip++;
}
inline void pc(char c){
if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
*op++=c;
}
inline ll read(){
register ll x=0,ch=gc(),w=1;
for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
return w*x;
}
template<class I>
inline void write(I x){
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);pc(x%10+'0');
}
class flusher_{
public:
~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
}IO_flusher;
}
using namespace IO;
ll quickmod (ll a, ll b ,ll c)
{
ll ret=1%c;
while(b){
if(b&1)
ret=ret*a%c;
a=a*a%c;
b=b>>1;
}
return ret;
}
ll inv(ll x) {
return quickmod(x, mod-2, mod);
}
ll C(ll n,ll m){
return fac[n]*(inv(fac[n-m])*inv(fac[m])%mod)%mod;
}
int main()
{
fac[0]=1;
for(int i=1;i<=maxn;i++){
fac[i]=fac[i-1]*i%mod;
}
t=read();
while(t--){
n=read();m=read();
write(C(n+m-2,n-1));
pc('\n');
}
}
L Defeat the monster
排個序,滑動窗口過一遍就行了。
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
typedef long long ll;
const int maxn=2e5+10;
using namespace std;
namespace IO{
char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
inline char gc(){
if(ip!=ip_)return *ip++;
ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
return ip==ip_?EOF:*ip++;
}
inline void pc(char c){
if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
*op++=c;
}
inline ll read(){
register ll x=0,ch=gc(),w=1;
for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
return w*x;
}
template<class I>
inline void write(I x){
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);pc(x%10+'0');
}
class flusher_{
public:
~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
}IO_flusher;
}
using namespace IO;
int a[maxn],n;
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
sort(a+1,a+1+n);
int i=1,j=1;
int ans=0;
while(i<=j&&j<=n){
if(a[j]-a[i]>5){
i++;
}
else{
ans=max(ans,j-i+1);//基本都在指針變化前
j++;
}
}
write(ans);
pc('\n');
return 0;
}