6.2~6.8
ITA练习赛2
B

这道签到题我交了7发......
最初把题目看成了任意两个元素互素,结果怎么提交都不对,就发现看错题了...
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int n,a[maxn];
map <int,int> ma;
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n;
a[0] = -1;
bool pd;
for(int i=1;i<=n;i++) cin >> a[i];
for(int i=2;i<=n;i++){
if(__gcd(a[i],a[i-1]) != 1){
cout << "-1\n";
return 0;
}
}
cout << "0\n";
return 0;
}
C

构造
由于冻结的影响范围为3,因此以三个为一组,只要每组中间的倾洼满足gcd就行。
这样分组的话,最后还会剩下一些倾洼,res可能为0,1,2,分类讨论然后构造。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int m = 999999999;
int n,a[maxn],cnt = 0;
queue <int> q1,q2;
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n;
for(int i=1;i<=n;i++){
if(__gcd(i,m) != 1) cnt++, q1.push(i);
else q2.push(i);
}
if(cnt < ceil(n*1.0/3.0)) {cout << "Baka!\n"; return 0;}
int index = 0, res = n%3;
while(index < n-res){
if(!q2.empty()){
cout << q2.front() << ' ';
q2.pop(),index++;
}
else{
cout << q1.front() << ' ';
q1.pop(),index++;
}
cout << q1.front() << ' ';
q1.pop(),index++;
if(!q2.empty()){
cout << q2.front() << ' ';
q2.pop(),index++;
}
else{
cout << q1.front() << ' ';
q1.pop(),index++;
}
}
if(res == 1) cout << q1.front() << ' ';
else if(res == 2){
cout << q1.front() << ' ';q1.pop();
if(!q2.empty()) cout << q2.front() << ' ';
else cout << q1.front() << ' ';
}
cout << '\n';
return 0;
}
E

一个DFS+两个BFS(其实DFS可以不要)
用x_[]和y_[]来记录激光区域,只要能在这些x或者y节点发射激光就能到E
先处理E,从E开始bfs,能够走到的地方的x和y都算成激光区域;到达边界时把边界处相邻的'#'的x和y给算成激光区域。
再从S开始bfs,对每一步的x和y做判断,如果x或者y在激光区域里,就能到E
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1002;
int n,m,explore[][2] = {1,0,-1,0,0,1,0,-1};
char room[maxn][maxn];
bool jig[maxn][maxn],vis[maxn][maxn],x_[maxn],y_[maxn];
bool visd[maxn][maxn];
class node{
public:
int x,y;
}s,e;
queue <node> d;
inline bool check1(node a){
return room[a.x][a.y] == '.' && !vis[a.x][a.y] && a.x>=1 && a.x<=n && a.y>=1 && a.y<=m;
}
inline bool check2(node a){
return room[a.x][a.y] == '.' && !jig[a.x][a.y] && a.x>=1 && a.x<=n && a.y>=1 && a.y<=m;
}
inline bool check3(node a){
return room[a.x][a.y] == '.' && !visd[a.x][a.y] && a.x>=1 && a.x<=n && a.y>=1 && a.y<=m;
}
void dfs(node a){
visd[a.x][a.y] = 1;
for(int i=0;i<4;i++){
node next = {a.x+explore[i][0],a.y+explore[i][1]};
if(check3(next)) dfs(next);
else if(next.x>=1 && next.x<=n && next.y>=1 && next.y<=m) d.push(next);
}
}
void bfse(node a){
queue <node> q;
q.push(a);
jig[a.x][a.y] = 1;
x_[a.x] = 1, y_[a.y] = 1;
while(!q.empty()){
//cout << "666" << endl;
node start = q.front();
q.pop();
node next;
for(int i=0;i<4;i++){
next.x = start.x + explore[i][0];
next.y = start.y + explore[i][1];
if(check2(next)){
q.push(next);
jig[next.x][next.y] = 1;
x_[a.x] = 1, y_[a.y] = 1;
}
}
}
}
void bfss(node a){
while(!d.empty()){
node c = d.front();
d.pop();
x_[c.x] = 1, y_[c.y] = 1;
}
queue <node> q;
q.push(a);
vis[a.x][a.y] = 1;
while(!q.empty()){
node start = q.front();
//cout << "777" << endl;
if(jig[start.x][start.y]) {cout << "YES\n";return;}
if(x_[start.x] || y_[start.y]) {cout << "YES\n";return;}
q.pop();
node next;
for(int i=0;i<4;i++){
next.x = start.x + explore[i][0];
next.y = start.y + explore[i][1];
if(check1(next)){
vis[next.x][next.y] = 1;
q.push(next);
}
}
}
cout << "NO\n";
}
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> room[i][j];
if(room[i][j] == 'S') s = {i,j};
if(room[i][j] == 'E') e = {i,j};
}
}
bfse(e);
dfs(e);
bfss(s);
return 0;
}
F

求第$ a^b $项,这里用快速幂算出值,快速幂的实现过程种注意a和ans取模,否则会爆
然后就是皮萨诺周期
皮萨诺周期
模$ m \(下的斐波那契数列的最小正周期,且周期\) T ≤ 6m \(,取等条件为\) m=2×5^k $
主要就是找一个皮萨诺周期$ T $
$ F(a^b)\ %\ c \iff F(a^b\ %\ T) \iff F(a\ %\ T)^b $
显然,当long long都爆了,正常会去想unsigned long long行不行......偏偏我就没去想
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
const int maxn = 6005;
int fb[maxn];
int fp(int a,int n,int c){
int ans = 1;
a %= c;
while(n){
if(n&1) ans = ans * a % c;
a = a * a % c;
n >>= 1;
}
return ans;
}
signed main(void){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t; cin >> t;
while(t--){
int a,b,c;
cin >> a >> b >> c;
fb[0] = 0, fb[1] = 1;
int index = 1;
while(++index){
fb[index] = (fb[index-1] + fb[index-2])%c;
if(fb[index] == 1 && fb[index-1] == 0){
c = index-1;
break;
}
}
cout << fb[fp(a,b,c)] << '\n';
}
return 0;
}

浙公网安备 33010602011771号