T1
限制
时间限制:3s。
空间限制:512MB。
问题描述
王牌校长波波牛手下有 n 个特工,每个特工有一个主密码和一个辅助密码。
当两个特工遇见,他们会向对方展示自己的辅助密码,然后计算自己的主密码与对方的辅助密码的和。如果两位特工的计算结果相同,则他们匹配成功。
有多少对不同的特工遇见时能匹配成功?
输入格式
第一行有一个整数 n,代表特工个数 。
下面有 n 行,第 i+1 行有两个数字 xi 和 yi,依次代表特工 i 的主密码和辅助密码。
输出格式
一个整数,表示遇见时能匹配成功的特工对数。
注意到答案可能较大,需要合适的存储和输出方式。
思路
首先要计算的就是xi-yj=xj-yi的个数,简单移项就变为xi+yi=xj+yj的个数,所以用一个unordered_map就可以解决这个问题
代码
#include<bits/stdc++.h>
using namespace std;
unordered_map<string,long long> mp;
int n;
long long ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for (int i=1;i<=n;i++) {
long long x,y;
cin>>x>>y;
long long xy=x-y;
string xz;
if (xy<0){
xz="-";
xy=abs(xy);
}
while(xy){
int wz=xy%10;
xz+=('0'+wz);
xy/=10;
}
// cout<<xz<<"\n";
ans+=mp[xz];
mp[xz]++;
}
cout<<ans;
return 0;
}
T2
问题描述
小 D 和小 Y 在玩一个叫提克塔可头的游戏。游戏在一个 3×3 的棋盘上进行。初始时棋盘上所有位置都是空的(用 . 表示)。从小 D 开始,两人交替行动。小 D 每次会选择一个空格子下一颗白子(用 X 表示),小 Y 会选择一个空格子下一颗黑子(用 O 表示)。当有出现某一行、某一列、或某条对角线上的三个格子里全都是某一方的棋子时,该方获胜。
小 D 和小 Y 下棋下累了,想考考你。他们给你看了 t 个提克塔可头棋盘。对每个棋盘,请你判断,棋盘上的局面是否是可以达到的。如果是,还请你计算出,从当前局面开始,有多少个棋局是小 D 赢,有多少个棋局是小 Y 赢。一个“棋局”是指从当前局面开始,直到下完这盘棋,过程中两人的所有行动。两个棋局不同,当且仅当存在某一方在某一步下的位置不同。
输入格式
第一行一个正整数 t。
接下来 t 行,每行一个长度为 9 的字符串,包含 ., X, O 三种字符,描述一个棋盘上的局面。前三个字符是棋盘的第一行,然后第二行、第三行。
输出格式
输出 t 行。每行两个整数。
如果该棋盘上的局面不可能达到,输出两个 −1。
否则,输出从当前局面开始,有多少个棋局是小 D 赢,有多少个棋局是小 Y 赢。
思路
这题我也是无语了,就是直接暴力把所有情况处理出来成一个DAG然后再用拓扑排序就可以得到所有答案了,最后O(1)输出,当时确实没有想到这么无脑的做法,话说想到了也写不出来吧
#include<bits/stdc++.h>
using namespace std;
const int N=19683;
int pw3[10];
int win[N];
vector<int> g[N];
int id[N];
int ans1[N],ans2[N];
int f(int st,int i,int j){
return (st/pw3[8-((i-1)*3+j-1)])%3;
}
int checkw(int st){
if (f(st,1,1)!=0&&f(st,1,1)==f(st,1,2)&&f(st,1,1)==f(st,1,3)) return f(st,1,1);
if (f(st,2,1)!=0&&f(st,2,1)==f(st,2,2)&&f(st,2,1)==f(st,2,3)) return f(st,2,1);
if (f(st,3,1