time:2019.12.01
水題不少,難題也有幾個。
Problem A:NEFU2020 庫特選數
從1到1e6掃一遍,判斷整除情況:若當前數在數組中且能整除,商也在數組中,則符合條件。注意特判完全平方的情況。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int n, m, x, a[maxn];
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
memset(a, 0, sizeof(a));
for(int i=1; i<=n; i++)
{
cin>>x;
a[x]++;
}
bool flag = false;
if(m)
{
for(int i=1; i<=maxn-10; i++)
if(m%i==0 && a[i])
{
int tmp = m/i;
if(tmp > 1e6) continue;
if(tmp == i)
if(a[tmp] >= 2) flag = true;
if(tmp != i)
if(a[tmp] >= 1)
flag = true;
//cout<<"s"<<flag<<endl;
}
}
else
if(a[0]) flag = true;
if(flag) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
Problem B:NEFU2019 庫特刪數
奇-偶 = 奇,偶-奇 = 奇。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int n, x, even=0, odd=0;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
long long sum = 0;
for(int i=1; i<=n; i++)
{
cin>>x;
sum += x;
if(x%2) odd++;
else even++;
}
if(sum%2)
{
if(even>1 || odd>1) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
else
{
if(odd>=1 && even>0) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
Problem C:NEFU2031 凱撒密碼
簡單的字符轉換操作。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
string str;
int n;
int main()
{
ios::sync_with_stdio(false);
while(cin>>str>>n)
{
for(int i=0; i<str.size(); i++)
if(str[i]>='a'+n && str[i]<='z') str[i] -= n;
else str[i] += 26-n;
cout<<str<<endl;
}
return 0;
}
Problem D:NEFU2033 神祕數字
按題意模擬即可。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int n, m;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
int a=1, b=0;
for(int i=1; i<=n; i++)
{
a *= 10;
b = b*10+9;
}
long long ans = 0;
for(int i=a/10; i<=b; i++)
{
int sum = 0;
int j = i;
while(j)
{
sum += j%10;
j /= 10;
}
if(sum == m) ans += i;
}
cout<<ans<<endl;
return 0;
}
Problem E:NEFU2039 why的概率論
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int t, x, y;
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cin>>x>>y;
if(!x) cout<<"0 / 1"<<endl;
else
{
y += x;
x *= 4;
cout<<x/__gcd(x, y)<<" / "<<y/__gcd(x, y)<<endl;
}
}
return 0;
}
Problem F:NEFU100 快來找一找
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int m, num;
int main()
{
ios::sync_with_stdio(false);
while(cin>>m)
{
int maxn = -0x3f3f3f3f;
while(m--)
{
cin>>num;
maxn = max(maxn, num);
}
cout<<maxn<<endl;
}
return 0;
}
Problem G:NEFU2034 第幾個質數
這道題不篩也可以。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+1;
int cnt=0, max1=1e3, prime[maxn], rev[maxn];
bool flag[maxn];
void init()
{
fill(flag, flag+maxn, 1);
flag[0]=0;
flag[1]=0;
for(int i=2; i<=max1; i++)
{
if(flag[i])
{
prime[++cnt] = i;
rev[i] = cnt;
}
for(int j=1; j<=cnt&&prime[j]*i<=max1; j++)
{
flag[prime[j]*i] = 0;
if(!(i%prime[j])) break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
init();
int n;
while(cin>>n)
{
if(flag[n])
cout<<rev[n]<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
Problem H:NEFU2065 小x愛料理
木桶效應,短板爲決定方。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int t, a, b, c, u, v, w;
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cin>>u>>v>>w>>a>>b>>c;
int minn = 0x3f;
minn = min(minn, u/a);
minn = min(minn, v/b);
minn = min(minn, w/c);
cout<<minn<<endl;
}
return 0;
}
Problem I:NEFU2032 數字黑洞
使用一個標記數組來標記出現過的數字。
進行死循環,如果標記數組裏面已經是 1 了說明這個數出現過了,直接退出死循環,最終的數是 1 的話就輸出循環的次數,不是的話輸出最後這個數字。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int n;
bool flag[1005];
int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
memset(flag, 0, sizeof(flag));
flag[n] = 1;
int ans = 0;
while(n != 1)
{
int cnt = 0;
while(n)
{
int tmp = n%10;
cnt += tmp*tmp;
n /= 10;
}
n = cnt;
if(!flag[n])
{
flag[n] = 1;
ans++;
}
else
{
ans = n;
break;
}
}
cout<<ans<<endl;
}
return 0;
}
Problem J:NEFU2022 庫特打撲克
這真是道大模擬。校賽沒做出來,補題的時候卡了一宿。卡就卡在改變數字後沒有重新計數。
引用下題解文檔的原話:
典型的模擬題,沒什麼太多可說的,按照題意枚舉即可,看主代碼手的手速吧(笑)。雖然算不上大模擬,但是還是有幾個細節需要注意的,我來說一說這些細節。
- 有個彩蛋,是第 11 條的上述規則改動超過 8 條,也就是說第 11 個條件是前 10 個條件觸發至少 9 個纔會觸發的,首先 7 與 8 一定是互斥的,其次我們可以發現 3 和 9 也是互斥的,所以第 11 個條件一定不會觸發,如果發現不了這一點要多寫一個唯一分解定理增添不少碼量
- 我們很容易習慣性認爲進行完規則 12 一定會進行規則 13,然而規則 12 中最後一次改變得分的規則有可能是規則 9,再進行完規則 9 後手牌點數會發生變化導致不一定再保證還有點數 2 的牌所以規則 13 要再次判斷一下
- 規則 12 中說的上次改變得分的規則,不是上次執行的規則,比如你上次執行了 10,但是你手上沒有 A,那麼規則 10 沒有改變你的得分,這樣規則 10 就不是上次改變得分的規則
注意到這三點,碼的還沒有錯誤的話應該就能 ac 啦。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
string po[5];
int _first[5], huase[5], pai[15];
int red=0, black=0, _last, minn=0x3f3f3f3f;
long long sum = 0;
long long five(long long n) // 規則5
{
long long m=0;
int i;
for(i=1; i*i<n; i++)
if(!(n%i)) m += (i+n/i);
if(i*i == n) m += i;
return m;
}
int main()
{
//ios::sync_with_stdio(false);
for(int i=0; i<5; i++)
cin>>po[i];
for(int i=0; i<5; i++)
{
if(po[i].size() == 3) _first[i] = 10;
else if(po[i][0]>='2' && po[i][0]<='9') _first[i] = po[i][0]-'0';
else _first[i] = 10;
minn = min(minn, _first[i]);
sum += _first[i]; // 初始得分
// D方塊 H紅桃 C梅花 S黑桃
if(po[i][po[i].size()-1]=='D' || po[i][po[i].size()-1]=='H') red++;
else black++;
if(po[i][po[i].size()-1] == 'D') huase[0]++;
if(po[i][po[i].size()-1] == 'H') huase[1]++;
if(po[i][po[i].size()-1] == 'C') huase[2]++;
if(po[i][po[i].size()-1] == 'S') huase[3]++;
}
for(int i=0; i<5; i++)
{
if(po[i][0]>='2' && po[i][0]<='9') pai[po[i][0]-'0']++;
else if(po[i][0] == '1') pai[10]++;
else if(po[i][0] == 'J') pai[11]++;
else if(po[i][0] == 'Q') pai[12]++;
else if(po[i][0] == 'K') pai[13]++;
else if(po[i][0] == 'A') pai[14]++;
}
sum++;
sum += pai[11]*_first[0]; // 規則1
sum *= 2; // 規則2
if(huase[0] && huase[1] && huase[2] && huase[3]) sum *= 2; // 規則3
sum += abs(black-red); //規則4
if(!(sum%2)) sum += five(sum); // 規則5
//sum *= 2;
if(pai[7] == 4) sum -= 121; // 規則6
if(sum >= 0) // 規則7
{
sum += minn;
_last = 7;
}
if(sum < 0) // 規則8
{
sum *= (-1);
_last = 8;
}
if(huase[0] >= 3) // 規則9
{
sum++;
for(int i=0; i<5; i++)
{
if(po[i][0] == '2') po[i][0] = '5';
else if(po[i][0] == '5') po[i][0] = '2';
else if(po[i][0] == '6') po[i][0] = '9';
else if(po[i][0] == '9') po[i][0] = '6';
}
_last = 9;
// 牌計數改變
swap(pai[2], pai[5]);
swap(pai[6], pai[9]);
}
bool shunzi = 0;
for(int i=2; i<=10; i++)
if(pai[i] && pai[i+1] && pai[i+2] && pai[i+3] && pai[i+4])
{
shunzi = 1;
//break;
}
if(shunzi && pai[14]) // 規則10
{
sum += 5*pai[14];
_last = 10;
}
// 規則11不可能實現
if(pai[2]) // 規則12
{ // 跳轉到上次改變得分的規則
if(_last == 7)
{
minn = 0x3f3f3f3f;
for(int i=0; i<5; i++)
{
if(po[i].size() == 3) _first[i] = 10;
else if(po[i][0]>='2' && po[i][0]<='9') _first[i] = po[i][0]-'0';
else _first[i] = 10;
minn = min(minn, _first[i]);
}
sum += minn;
}
if(_last == 8)
if(sum < 0) sum *= (-1);
if(_last == 9)
{
sum++;
for(int i=0; i<5; i++)
{
if(po[i][0] == '2') po[i][0] = '5';
else if(po[i][0] == '5') po[i][0] = '2';
else if(po[i][0] == '6') po[i][0] = '9';
else if(po[i][0] == '9') po[i][0] = '6';
}
}
if(_last == 10) sum += 5*pai[14];
}
bool after_change_2 = 0;
for(int i=0; i<5; i++)
if(po[i][0] == '2')
{
after_change_2 = 1;
//break;
}
if(after_change_2) sum *= 2;
cout<<sum<<endl;
return 0;
}
gls還是鈦鏹了。
Problem K:NEFU2061 庫特的鴿鴿們
還是那句話,gls鈦鏹了。
對於每隻鴿鴿,只有最後一次 1 操作是決定性的,在此之前的操作都不會影響最終結果。我們可以分別對每隻鴿鴿記一下最後一次操作 1 的時間,再對操作 2 求一下最大後綴。
對於每隻鴿鴿,最終答案即爲:
max(最後一次操作 1 的值,在最後一次 1 操作之後所有操作 2 的最大值)
這樣可以在 O(n + q)的複雜度內實現。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
int n, q, a[maxn], change[maxn], p[maxn], maxx[maxn];
int main()
{
//ios::sync_with_stdio(false);
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i];
cin>>q;
for(int i=1; i<=q; i++)
{
int op, x, y;
cin>>op;
if(op == 1)
{
cin>>x>>y;
change[x] = y;
p[x] = i;
}
else cin>>maxx[i];
}
for(int i=q-1; i>=1; i--)
maxx[i] = max(maxx[i], maxx[i+1]);
for(int i=1; i<=n; i++)
{
if(i>1) cout<<" ";
if(p[i]) cout<<max(change[i], maxx[p[i]]);
else cout<<max(maxx[1], a[i]);
}
return 0;
}
Problem L:NEFU2063 小老鼠走迷宮
遞推,注意long long。
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
int a, b;
long long maze[55];
int main()
{
ios::sync_with_stdio(false);
maze[1] = 1;
maze[2] = 2;
for(int i=3; i<=54; i++)
maze[i] = maze[i-1]+maze[i-2];
while(cin>>b>>a)
cout<<maze[a-b]<<endl;
return 0;
}