A
- A 签到,模拟
题意:
找出字符串(可能有空格)中所有的数,不能有前导0,“00000”输出0。
#include <bits/stdc++.h>
using namespace std;
string s;
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
while(getline(cin,s)) {
vector<int> temp;
for(char c:s){
if(c>='0' && c<='9'){
int num=int(c-'0');
temp.emplace_back(num);
} else{
if(c==' ') continue;
bool flag=true;
if(int(temp.size())!=0){
for(int i=0; i<int(temp.size()); ++i) {
int x=temp[i];
if(x!=0) flag=false;
if(flag && x==0 && i!=int(temp.size())-1) continue;
cout<<x;
}
cout<<' ';
temp.clear();
}
}
}
if(int(temp.size())!=0){
bool flag=true;
for(int i=0; i<int(temp.size()); ++i) {
int x=temp[i];
if(x!=0) flag=false;
if(flag && x==0 && i!=int(temp.size())-1) continue;
cout<<x;
}
}
cout<<'\n';
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}
B
- B
签到
题意:
给你n个数,让你找几个数做&操作,得出来的数最大。
思路:
拍个序,最大的那个数就是答案,因为和其他数&肯定是亏的。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=(int)1e5+100;
ll tc,n,a[maxn],bit[100];
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
cin>>tc;
while(tc--){
memset(bit,0,sizeof(bit));
cin>>n;
for(int i=0; i<n; ++i){
cin>>a[i];
}
sort(a, a+n);
cout<<a[n-1]<<'\n';
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}
C
- C
博弈,必胜必败态打表,规律
题意:
有n个石子,轮流取,可取的数目为2的n次,1,2,4,8,…,每人都采取最优策略,问谁能赢。
思路:
看了大佬说可以想到2的n次对3取模的规律,我反正想不到,没那智商就只能打表了找规律了,必胜必败态打表代码在注释里。
#include <bits/stdc++.h>
using namespace std;
int tc,n,dp[1000];
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
cin>>tc;
while(tc--){
cin>>n;
if(cnt%3!=0) cout<<"Alan"<<'\n';
else cout<<"Frame"<<'\n';
}
// dp[0]=0;
// dp[1]=1;
// dp[2]=1;
// dp[3]=0;
// dp[4]=1;
// dp[5]=1;
// for(int i=6; i<=40; ++i){
// for(int j=0;(1<<j)<=i;++j){
// int temp=i-(1<<j);
// if(dp[temp]==0) dp[i]=1;
// }
// }
// for(int i=1; i<=30; ++i) cout<<i<<' '<<dp[i]<<endl;
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}
D
dp,01翻转(单个,1~n)
- D
题意:
给你长度为n的01序列,现在你可以做两种操作。
1.把某个数翻转。
2.把前1~x个数翻转。
现在问你做多少次才能变成全是0的序列。
思路:
dp。
维护前n个都变成0和1的最少次数。
#include <bits/stdc++.h>
using namespace std;
const int maxn=(int)1e5+100;
const int INF=0x3f3f3f3f;
int n,a[maxn],c1[maxn],c0[maxn];
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
cin>>n;
memset(c0,INF,sizeof(c0));
memset(c1,INF,sizeof(c1));
c0[0]=c1[0]=0;
for(int i=1; i<=n; ++i){
cin>>a[i];
if(a[i]==1) {
c0[i]=min(c0[i-1]+1, c1[i-1]+1);
c1[i]=min(c1[i-1], c0[i-1]+1);
} else if(a[i]==0){
c0[i]=min(c0[i-1], c1[i-1]+1);
c1[i]=min(c1[i-1]+1, c0[i-1]+1);
}
}
cout<<min(c0[n], c1[n]+1)<<'\n';
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}
E
- E
最短路,用位建图,新奇!
题意:
给你n个数ai,现在让你从1号点走到n号点,首先如果a[i]&a[j]!=0
的话,i到j才有一条无向边,否则他俩之间就没边,代价是lowbit(a[i]&a[j])
现在问你从1走到n的最小花费是多少。不能到达就输出impossible。
思路:
位思想。
从来没做过用位建图的,学到了。
对于每个a[i],如果i位上是1,那就连一条a[i]到i位那个点的单向边,长度为(1<<i)
,然后连一条i位那个点到a[i]的单向边,长度为0。然后就没了,整个图跑个dijkstra就完事了。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 40*100000+100; //点数
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
ll tc,n,a[maxn],bit[40];
struct node {
int id;
ll w;
node(){}
node(int a, ll b) : id(a), w(b) {} //hdu6805 美好的回忆:>
friend bool operator < (node a, node b) {return a.w > b.w;}
};
vector<node> G[maxn];
bool vis[maxn];
ll dis[maxn];
void dij(int s, int n) {
priority_queue<node> q;
while (!q.empty()) q.pop();
node cur;
for (int i = 1; i <= n; ++i) {
dis[i] = INF;
vis[i] = 0;
}
dis[s] = 0;
q.push(node(s, dis[s]));
while (!q.empty()) {
cur = q.top();
q.pop();
if (vis[cur.id]) continue;
vis[cur.id] = 1;
for (node to : G[cur.id]) {
if (!vis[to.id] && dis[to.id] > dis[cur.id] + to.w) { //dis[to.id] > to.w 就变成了堆优化prim
dis[to.id] = dis[cur.id] + to.w;
q.push(node(to.id, dis[to.id]));
}
}
}
}
void init(int n) {
for (int i = 0; i <= n; ++i) G[i].clear();
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.precision(10);cout << fixed;
#ifdef LOCAL_DEFINE
freopen("input.txt", "r", stdin);
#endif
cin>>tc;
while(tc--){
cin>>n;
init(40*100000+10);
memset(bit,0,sizeof(bit));
for(int i=1; i<=n; ++i){
cin>>a[i];
ll ta=a[i], now=0;
while(ta>0){
if(ta%2==1) {
G[i].emplace_back(node(n+1+now, (1LL<<now)));
G[n+1+now].emplace_back(node(i, 0));
bit[now]++;
}
++now;
ta/=2;
}
}
dij(1, n+60);
if(dis[n]==INF) cout<<"Impossible"<<'\n';
else cout<<dis[n]<<'\n';
}
#ifdef LOCAL_DEFINE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}