题意:给你多个钉子距离地面的距离,并告诉每个钉子绑的绳子的长度,每个绳子一段还会连在糖果一端,求最少隔断多少绳子可以将糖果放在地面
题解:思维题
如果一个钉子离地面距离比绳子长小的话,那么则不需要隔断,那么剩下就是需要隔断绳子数量
# include <bits/stdc++.h>
using namespace std;
# define int long long
const int N=1e5+10;
int t;
void solve() {
int n;
cin>>n;
int sum=0;
for(int i=1; i<=n; i++) {
int x,y;
cin>>x>>y;
if(y<x) {
sum++;
}
}
cout<<sum<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--) {
solve();
}
}
B
题意:就是三个人玩井字棋游戏,三个人代表三个符号,.代表未填入给你3*3的局面
问有人获胜没
题解:模拟即可
# include <bits/stdc++.h> using namespace std; # define int long long const int N=1e5+10; int t; void solve() { char s[4][4]; for(int i=1; i<=3; i++) { for(int j=1; j<=3; j++) { cin>>s[i][j]; } } char s1='d'; for(int i=1; i<=3; i++) { if(s[i][1]==s[i][2]&&s[i][1]==s[i][3]&&s[i][1]!='.') { s1=s[i][1]; } } for(int i=1; i<=3; i++) { if(s[1][i]==s[2][i]&&s[1][i]==s[3][i]&&s[1][i]!='.') { s1=s[1][i]; } } if(s[1][1]==s[2][2]&&s[1][1]==s[3][3]&&s[1][1]!='.') { s1=s[1][1]; } if(s[1][3]==s[2][2]&&s[2][2]==s[3][1]&&s[1][3]!='.') { s1=s[1][3]; } if(s1=='d') { cout<<"DRAW"<<endl; } else { cout<<s1<<endl; } } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>t; while(t--) { solve(); } }
题意:就是n个人比赛,比赛一共有m个题目,h小时结束,每完成一道题累计一分,每个人每道题完成需要有ti个时间,如果分数相同则看罚时。 问每个人都按照最优选择,问第一个人排名多少
题解:贪心 每个人先完成自己用时最少的题
# include <bits/stdc++.h>
using namespace std;
# define int long long
const int N=2e5+10;
int t;
vector<int>d[N];
typedef struct stu {
int x,y,id;
} A;
A a[N];
bool cmp(A x,A y) {
if(x.x==y.x) {
if(x.y==y.y) {
return x.id<y.id;
}
return x.y<y.y;
}
return x.x>y.x;
}
void solve() {
int cnt=0;
int n,m,h;
cin>>n>>m>>h;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
int x;
cin>>x;
d[i].push_back(x);
}
sort(d[i].begin(),d[i].end());
}
for(int i=1; i<=n; i++) {
long long sum=0;
long long sum1=0;
long long cnt1=0;
for(auto j:d[i]) {
sum+=j;
if(sum>h) {
break;
}
sum1+=sum;
cnt1+=1;
}
a[cnt].x=cnt1;
a[cnt].y=sum1;
a[cnt].id=i;
cnt++;
}
sort(a,a+cnt,cmp);
for(int i=0; i<cnt; i++) {
if(a[i].id==1) {
cout<<i+1<<endl;
break;
}
}
for(int i=1; i<=n; i++) {
d[i].clear();
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--) {
solve();
}
}
D
题解:计算每个三角形的面积在计算与上个三角形重叠的面积
# include <bits/stdc++.h> using namespace std; # define int long long const int N=2e5+10; double a[N]; int t; void solve() { int n; double d,h; cin>>n>>d>>h; for(int i=1; i<=n; i++) { cin>>a[i]; } double sum=0; for(int i=1; i<=n; i++) { if(i==1) { sum+=d*h*0.5; } else { if(a[i]-a[i-1]>=h) { sum+=d*h*0.5; } else { sum+=d*h*0.5; double len=a[i]-a[i-1]; double k=h-len; double k2=k*d/h; sum-=k2*k*0.5; } } } cout<<fixed<<setprecision(6)<<sum<<endl; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>t; while(t--) { solve(); } }
E2
题解 :因为n肯定是1+k+k*k+..k的p次方构成,应为n最大为1e18,那么如果单纯暴力就必须枚举到1e9 但可以观察到当k>1e6 h后n只能有1+k+k*k构成
这样我们可以将k<=1e6构成n的数存储下来,当k>1e6构成的n可以用1+k+k*k=n表示
判断一元二次方程是否有解
# include <bits/stdc++.h> using namespace std; using LL=long long; set<long long>nums; int main() { for(long long k=2; k<=1000000; ++k) { long long val=1+k; long long p=k*k; for(int cnt=3; cnt<=64; ++cnt) { val+=p; if(val>1e18) { break; } nums.insert(val); if(p>(long long )(1e18)/k) { break; } p*=k; } } int t; cin>>t; for(int i=0; i<t; i++) { long long n; cin>>n; if(n<3) { cout<<"NO"<<endl; continue ; } long long d=4*n-3; long long sq=sqrt(d); long long sqd=-1; for(long long i=max(0ll,sq-5); i<=sq+5; ++i) { if(i*i==d) { sqd=i; break; } if(sqd!=-1&&(sqd-1)%2==0&&(sqd-1)/2>1) { cout<<"YES"<<endl; continue ; } } if(nums.count(n))cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
G
题解 :建图跑个最短路
建图思路:起点就是一开始生病的状态,然后枚举它可以到达的状态点。
有个东西需要处理,就是一个药能解决的状态是100001 副作用为010000
其中当前状态 110000 那么如果该状态用了这个药可以到达的状态应该是(1<<n)-1^100001&110000|010000
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int ttt;
cin >> ttt;
while (ttt--) {
int n, m;
cin >> n >> m;
bitset<10> tmp;
cin >> tmp;
int s = (int) tmp.to_ulong();
vector<pair<pair<int, int>, int>> edges(m);
for (int i = 0; i < m; i++) {
cin >> edges[i].second;
cin >> tmp;
edges[i].first.first = ((1 << n) - 1) ^ (int) tmp.to_ulong();
cin >> tmp;
edges[i].first.second = (int) tmp.to_ulong();
}
vector<int> dist(1 << n, INT_MAX);
dist[s] = 0;
set<pair<int, int>> q = {{0, s}};
while (!q.empty()) {
auto [d, v] = *q.begin();
q.erase(q.begin());
for (int i = 0; i < m; i++) {
int to = v & edges[i].first.first;
to |= edges[i].first.second;
if (dist[to] > d + edges[i].second) {
q.erase({dist[to], to});
dist[to] = d + edges[i].second;
q.insert({dist[to], to});
}
}
}
if (dist[0] == INT_MAX) dist[0] = -1;
cout << dist[0] << '\n';
}
return 0;
}