你有一个骰子,扔两次,得到的数字和等于
k
的方案是多少,其中(3, 4) 和 (4,3)属于一种方案
显然小于2和大于12的方案都是0
其他的模拟一下就行
//Work by: Chelsea
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, op;
int x, y, z;
ll a, b, c;
string s, t;
int tr[MAX];
void work(){
cin >> n;
if(n > 12 || n < 2)cout << 0 << endl;
else {
int num = 0;
for(int i = 1; i <= 6; ++i){
if(n - i < i)break;
if(n - i >= 1 && n - i <= 6)++num;
}
cout << num << endl;
}
}
int main(){
io;
int tt;cin>>tt;
for(int _t = 1; _t <= tt; ++_t){
work();
}
return 0;
}
n个人吃旋转小火锅,转盘上最开始什么都没有,每个人都只吃一种东西,记作
a[i]
,火锅会旋转k
轮,第i
轮轮到编号为k%n
的人吃东西,如果当前锅里没有他喜欢吃的东西,他就会让人在锅中放他喜欢吃的东西,此时他不能吃;如果当前锅中有他喜欢吃的东西,那就会直接吃掉。问k
轮后每个人吃的东西的数量
首先,如果对于某个人,
如果他喜欢吃的食物在这n个人中是独一无二的,那我们只需要计算他能吃几轮
lun[i]
,答案就是lun[i]/2
,因为他只能在这一轮放,在下一轮吃如果他喜欢吃的食物在这
n
个人中不是独一无二的,且有相同爱好的人的数量是num
,记pos
是在具有相同爱好中第几个出现的
- 如果
num
是偶数,
- 则
pos
是奇数的人一定是吃不到的pos
是偶数的人是一定每轮都有的吃- 如果
num
是奇数,
- 则
pos
是奇数的人吃到的数量是 ⌊ l u n [ i ] 2 ⌋ \lfloor\frac{lun[i]}{2}\rfloor ⌊2lun[i]⌋pos
是偶数的人吃到的数量是 ⌈ l u n [ i ] 2 ⌉ \lceil\frac{lun[i]}{2}\rceil ⌈2lun[i]⌉
//Work by: Chelsea
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, op;
int x, y, z;
ll a, b, c;
string s, t;
int tr[MAX];
int lun[MAX];
bool vis[MAX];
int ans[MAX];
void work(){
cin >> n >> k >> m;
map<int, int>mp;
for(int i = 0; i < n; ++i){
vis[i] = 0;
cin >> tr[i];
++mp[tr[i]];
if(mp[tr[i]] % 2)vis[i] = 1;
}
for(int i = 0; i < n; ++i){
lun[i] = m / n + ((m % n > i) ? 1 : 0);
}
for(int i = 0; i < n; ++i){
if(mp[tr[i]] == 1)ans[i] = lun[i] / 2;
else{
if(mp[tr[i]] % 2 == 0){
if(vis[i])ans[i] = 0;
else ans[i] = lun[i];
}
else{
if(vis[i])ans[i] = lun[i] / 2;
else ans[i] = (lun[i] + 1) / 2;
}
}
cout << ans[i] << " \n"[i == n - 1];
}
}
int main(){
io;
int tt;cin>>tt;
for(int _t = 1; _t <= tt; ++_t){
work();
}
return 0;
}
石头剪刀布游戏,现在Alice和Bob有同数量的卡片,两个人互相知道对方的卡片的种类和数量
现在Bob先出卡片,Alice再出,Alice赢了则分数+1,Bob赢了则分数-1,Alice想让分数尽可能大,Bob想让分数尽可能小,问分数最后是多少
贪心,Bob的出牌顺序是无所谓的,Bob出一张牌,Alice先选能吃掉他的牌,如果没有了的话,就选与他种类相同的牌,如果还没有,则只能出被他吃的牌,计算答案就行
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define int long long
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, op;
int x, y, z;
ll a, b, c;
string s, t;
int tr[MAX];
int Bob[5], Alice[5];
int id[5];
void work(){
id[1] = 2;id[2] = 3;id[3] = 1;
for(int i = 1; i <= 3; ++i)cin >> Bob[i];
for(int i = 1; i <= 3; ++i)cin >> Alice[i];
int ans = 0;
for(int i = 1; i <= 3; ++i){
int idd = id[i];
if(Alice[idd] >= Bob[i]){
ans += Bob[i];
Alice[idd] -= Bob[i];
}
else{
ans += Alice[idd];
Bob[i] -= Alice[idd];
Alice[idd] = 0;
if(Alice[i] >= Bob[i]){
Alice[i] -= Bob[i];
Bob[i] = 0;
}
else{
ans -= (Bob[i] - Alice[i]);
Alice[i] = 0;
Bob[i] = 0;
}
}
}
cout << ans << endl;
}
signed main(){
io;
int tt;cin>>tt;
for(int _t = 1; _t <= tt; ++_t){
work();
}
return 0;
}
给你一个图,问最少加几条边能让图的dfs序是1 2 3…n
dfs + 贪心
建图的时候建一条从小节点到大节点的单向边就行
然后从1开始爆搜,遇到小于当前节点
tot
的就跳过,遇到大于当前节点的就说明需要连边了,更新答案和tot
,然后去dfs(tot-1)
,如果当前这个点有能连到tot
的边,那就说明不需要连边,直接更新tot
后去dfs(tot-1)
就行
//Work by: Chelsea
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m, k, op;
int x, y, z;
ll a, b, c;
string s, t;
vector<int>G[MAX];
int tot, ans;
void dfs(int u){
if(u > n)return;
for(auto v : G[u]){
if(v < tot)continue;
while(tot <= v){
if(v == tot){
++tot;
dfs(tot - 1);
}
else {
++tot;
++ans;
dfs(tot - 1);
}
}
}
}
void work(){
cin >> n >> m;
tot = 2;ans = 0;
for(int i = 1; i <= n; ++i)G[i].clear();
for(int i = 1; i <= m; ++i){
cin >> x >> y;
if(x > y)swap(x, y);
G[x].push_back(y);
}
G[1].push_back(n + 1);
for(int i = 1; i <= n; ++i){
sort(G[i].begin(), G[i].end());
G[i].erase(unique(G[i].begin(), G[i].end()), G[i].end());
}
dfs(1);
cout << ans << endl;
}
int main(){
io;
int tt;cin>>tt;
for(int _t = 1; _t <= tt; ++_t){
work();;
}
return 0;
}
队友写的,好像是模拟题
虽然说因为从不写模拟题导致天梯赛打崩了,但我还是不想补模拟,咕咕咕
构造一个全排列
a[i]
,使的a[i] + k = a[i+1]
的i
的数量最大
贪心就行
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 1000000 + 50
int n, m, k, x;
int tr[MAX];
void work(){
cin >> n >> k;
set<int>se;
for(int i = 2; i <= n; ++i)se.insert(i);
tr[1] = 1;
for(int i = 2; i <= n; ++i){
int p = tr[i - 1] + k;
if(p <= n && se.count(p)){
tr[i] = p;
se.erase(p);
}
else{
tr[i] = *se.begin();
se.erase(*se.begin());
}
}
for(int i = 1; i <= n; ++i)cout << tr[i] << " \n"[i == n];
}
int main(){
io;
work();
return 0;
}
n个点,每个点都有一个权值
c
,q次询问,每次询问都给你一个s
和p
,问从s
出发,到任意一个c<=p
的点最短距离是多少
多源bfs
因为权值
c
很小,我们可以开一个dis[i][j]
数组,表示从i
出发到达权值为j
的点的最短距离我们跑
100
次bfs,每次都把权值为i
的点塞到队列里面去求dis[i][j]
,跑完以后我们需要进一步的更新数组的含义为dis[i][j]
表示从i
出发到达权值小于等于j
的点的最短距离
dis[i][j] = min(dis[i][j], dis[i][j - 1])
对于每次询问就直接判断是不是
inf
后输出
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 100000 + 50
int n, m, k, x, y;
int tr[MAX];
vector<int>G[MAX];
int dis[MAX][105];
void bfs(int p){
queue<int>q;
for(int i = 1; i <= n; ++i){
if(tr[i] == p){
q.push(i);
dis[i][p] = 0;
}
}
while (!q.empty()) {
int u = q.front();q.pop();
for(auto v : G[u]){
if(dis[v][p] == inf){
q.push(v);
}
dis[v][p] = min(dis[v][p], dis[u][p] + 1);
}
}
}
void work(){
scanf("%d%d%d", &n, &m, &k);
mem(dis, inf);
for(int i = 1; i <= n; ++i)scanf("%d", &tr[i]);
for(int i = 1; i <= m; ++i){
scanf("%d%d",&x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i = 1; i <= 100; ++i)bfs(i);
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= 100; ++j){
dis[i][j] = min(dis[i][j], dis[i][j - 1]);
}
}
while (k--) {
scanf("%d%d",&x, &y);
if(dis[x][y] == inf)cout << -1 << endl;
else cout << dis[x][y] << endl;
}
}
int main(){
work();
return 0;
}
n个人处于同一个位置,距离机场的距离都是
x
,登机时间会改变k
次,每次都会给出一个a,b
表示从a
开始获知登机时间改变,且改变到b
,每个人有不同的速度,每个人在每次获知登机时间后都会进行一次判断,判断当前时间内能否到达机场,如果可以,就走,如果不可以,就一点也不走,问最终有几个点能到达机场
显然,不存在一个人走走停停的情况,也就是只要判断能走到,就一定会到
我们只需要找到所有时间段中最大的那一段,判断每个人在这一段能不能走到机场即可,注意别忘了最开始的那一段,还得开
longlong
#include
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
ll n, m, k, x;
ll tr[MAX];
ll t[MAX], p[MAX];
void work(){
cin >> n >> m >> k >> x;
for(int i = 1; i <= n; ++i)cin >> tr[i];
for(int i = 1; i <= m; ++i)cin >> t[i];
for(int i = 1; i <= m; ++i)cin >> p[i];
ll maxn = x;
for(int i = 1; i <= m; ++i)maxn = max(maxn, p[i] - t[i]);
ll ans = 0;
for(int i = 1; i <= n; ++i){
if(maxn * tr[i] >= k)++ans;
}
cout << ans << endl;
}
int main(){
io;
work();
return 0;
}
这次比赛是我找的21年的四川省赛,本来的计划是3人1机+打印题面,想认真打一场省赛,看看自己水平到底在哪里,但是被lls突如其来的通知給破防了,只能三人三机
一般来说都是我和djk一起开题,yj自己开题,我这边两个人边读边写,我手速快,所以我们俩想完以后我就直接写了,yj那边也是写了两个题,拿了两个一血,导致开局一个小时十一分钟我们队就7个题了,一度冲到了第五名,但是后来被E卡了俩小时,这个题我们知道思路是什么,但是dfs写少了,卡到写不出来,后来被yj先写出来了,djk写了个我们俩讨论的一个奇怪的做法,也都a了,蚂蚁题没思路也不想写,再加上yj有事,我们就索性3小时下班了…