k题迪杰斯特拉找不到错误,题解的坑我都没踩,c和d就是不知道为什么自己当时想不出来,j题题面看不懂,h就是线段树模板,今天真的太弟弟了,为此我还写了一首打油诗来警示自己:
菜就一个字,
一题说一次。
菜菜菜菜菜,
E D H J K。
A:第Q个全排列
一道规律题,先计算出(1~9)的n!并用数组存下来,然后举例就会发现,前(n - 1)!的首数字都是1,所以只要用(n - 1) / (n - 1)! + 1就可以得出第一位(n - 1的原因是序列是从1开始的),然后就会剩下(n % (n - 1)!),一样的方法,然后在剩下的里面找第几个就好了,以此类推就好,需要注意的是当n 模成了0的情况,那后面几位必定是最大序列,直接倒着输出就好了(当时还想着数组存,结果爆了)下面是代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ds[105],n,m,vis[105];
void init()
{
ds[0] = 1;ds[1] = 1;
for(int i = 2;i <= 10;i++) ds[i] = ds[i - 1] * i;
}
int main()
{
init();
while(cin >> n >> m){
int now = m;
memset(vis,0,sizeof(vis));
for(int i = 1;i <= n;i++){
if(now == 0){
for(int j = n;j >= 1;j--){
if(vis[j]) continue;
cout << j;
}
break;
}
int sum = 0;
int s = (now - 1) / ds[n - i] + 1;
for(int j = 1;j <= n;j++)
if(vis[j]) continue;
sum++;
if(sum == s){
cout << j;
vis[j] = 1;
break;
}
}
now = now % ds[n - i];
}
cout << endl;
}
return 0;
}
B:路线方案数
DP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans,n,dp[100005];
void init()
{
dp[0] = 1;
for(int i = 1;i <= 100000;i++) dp[i] = i;
}
int main()
{
init();
while(cin >> n){
ans = 0;
if(n == 1) ans = 2;
else
for(int i = 0;i < n;i++){
ans = ans + (dp[i] + dp[n - 1 - i]) * 2;
}
cout << ans << endl;
}
return 0;
}
C:饱了吗
结构体模拟题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans,n,m,vis[1005][1005],vi[1005],a,b,c,id,e;
double w,r,g;
string zf;
struct node{
int id;
double w,r,g;
int e;
}t[10005];
bool cmp(node x,node y)
{
if(x.w != y.w)
return x.w > y.w;
if(x.id != y.id)
return x.id > y.id;
}
int main()
{
while(cin >> n >> a >> b >> c){
int now = 0;
for(int i = 0;i < n;i++){
cin >> id >> w >> e >> r >> g;
if(a == 1 && e == 1 || a == 0)
if(r <= b && g <= c){
t[now].id = id; t[now].w = w; t[now].e = e; t[now].r = r; t[now].g = g;
now++;
}
}
sort(t,t + now,cmp);
for(int i = 0;i < now;i++){
cout << t[i].id << " " << t[i].w << " " << t[i].e << " " << t[i].r << " " << t[i].g << endl;
}
}
return 0;
}
D:好基友
题解,当时想着nlogn,想远了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,a[200010],b[200010];
int main()
{
while(~scanf("%d",&n)){
for(int i = 1;i <= n * 2;i++){
scanf("%d",&a[i]);
b[a[i]] = i;
}
int ans = 0;
for(int i = 1;i <= n * 2;i += 2){
int j = i + 1;
if((a[i] ^ 1) != a[i + 1]){
int s = b[(a[i] ^ 1)];
swap(b[(a[i] ^ 1)],b[a[i + 1]]);
a[s] = a[i + 1];
a[i + 1] = (a[i] ^ 1);
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
E:最多水容量
题解
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n,a[20005];
while(cin >> n){
for(int i = 1;i <= n;i++){
cin >> a[i];
}
int ans = 0;
int l = 1,r = n;
while(l <= r){
ans = max(ans,(r - l) * min(a[l],a[r]));
if(a[l] >= a[r]) r--;
else l++;
}
cout << ans << endl;
}
return 0;
}
F:寻找预言家
用vis数组存状态,暴力就好了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans,n,m,vis[1005][1005],vi[1005];
string zf;
int main()
{
while(cin >> n >> m){
memset(vis,0,sizeof(vis));
memset(vi,0,sizeof(vi));
for(int i = 0;i < m;i++){
int a,b;
cin >> a >> b;
vis[a][b] = 1;
vi[a] = 1;
}
ans = -1;
for(int i = 1;i <= n;i++){
if(!vi[i])
for(int j = 1;j <= n;j++){
if(i == j) continue;
if(!vis[j][i]) break;
if(j == n || i == n && j == n - 1){
ans = i;
}
}
if(ans != -1) break;
}
cout << ans << endl;
}
return 0;
}
G:LZY的计算器
倒着想,当m位奇数是加一除二,偶数除二,当n >= m时,ans加上就好
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans,n,m,vis[100005],vi[100005];
string zf;
int main()
{
while(cin >> n >> m){
if(n >= m) ans = n - m;
else{
ans = 0;
while(m > n){
if(m % 2){
m++;
ans++;
}
m /= 2;
ans++;
}
ans += n - m;
}
cout << ans << endl;
}
return 0;
}
H:弹药数量
线段树模板题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 50005;
ll n,a[maxn],tt;
struct Treenode{
ll l,r,s;
}t[maxn * 4];
void Update(int root)
{
t[root].s = t[root<<1|1].s + t[root<<1].s;
}
void BuildTree(int l,int r,int root)
{
if(l == r){
t[root].s = a[l];
return ;
}
int mid = (l + r) / 2;
BuildTree(l,mid,root<<1);
BuildTree(mid + 1,r,root<<1|1);
Update(root);
}
ll Query(int l,int r,int L,int R,int root)
{
if(l >= L && r <= R) return t[root].s;
int mid = (l + r) / 2;
Treenode ans;
ans.s = 0;
if(mid >= L) ans.s += Query(l,mid,L,R,root<<1);
if(mid < R) ans.s += Query(mid + 1,r,L,R,root<<1|1);
return ans.s;
}
void Tree_Update(int l,int r,int L,int R,int root,int x)
{
if(l >= L && r <= R){
t[root].s += x;
return ;
}
int mid = (l + r) / 2;
if(mid >= L) Tree_Update(l,mid,L,R,root<<1,x);
if(mid < R) Tree_Update(mid + 1,r,L,R,root<<1|1,x);
Update(root);
}
int main()
{
int now = 1;char s[10];
scanf("%d",&tt);
while(tt--){
scanf("%lld",&n);
for(int i = 1;i <= n;i++) scanf("%lld",&a[i]);
printf("Case %d:\n",now++);
BuildTree(1,n,1);
while(scanf("%s",&s)){
if(s[0] == 'E') break;
int l,r;
scanf("%d %d",&l,&r);
if(s[0] == 'Q'){
printf("%lld\n",Query(1,n,l,r,1));
}
if(s[0] == 'A'){
Tree_Update(1,n,l,l,1,r);
}
if(s[0] == 'S'){
Tree_Update(1,n,l,l,1,-r);
}
}
}
return 0;
}
I: 最长回文串长度
利用hash的思想,偶数全加,奇数则立个flag,再减一加上,最后再加flag
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans,n,vis[100005],vi[100005];
string zf;
int main()
{
while(cin >> zf){
memset(vis,0,sizeof(vis));
memset(vi,0,sizeof(vi));
for(int i = 0;i < zf.length();i++){
if(zf[i] >= 'a' && zf[i] <= 'z')
vis[zf[i] - 'a']++;
if(zf[i] >= 'A' && zf[i] <= 'Z')
vi[zf[i] - 'A']++;
}
int ma = 0;ans = 0;
for(int i = 0;i <= 26;i++){
if(vis[i] % 2 == 0) ans += vis[i];
else{
ans += vis[i] - 1;
ma = 1;
}
}
for(int i = 0;i <= 26;i++){
if(vi[i] % 2 == 0) ans += vi[i];
else{
ans += vi[i] - 1;
ma = 1;
}
}
ans += ma;
cout << ans << endl;
}
return 0;
}
J: 水流问题
www,看错题目以为是左上角和右下角是海,方法是bfs2次,看哪些块被经过2次。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1005][1005],n,m,vis[1005][1005],su[1005][1005];
int b[4][2] = {0,1,1,0,-1,0,0,-1};
struct node{
int x,y;
};
queue<node> ps;
bool OK(int x,int y)
{
if(x < 1 || y < 1 || x > n || y > m) return false;
return true;
}
void bfs()
{
while(!ps.empty()){
node cur = ps.front();
ps.pop();
for(int i = 0;i < 4;i++){
node nex = cur;
nex.x += b[i][0];
nex.y += b[i][1];
if(OK(nex.x,nex.y) && !vis[nex.x][nex.y] && a[nex.x][nex.y] >= a[cur.x][cur.y]){
vis[nex.x][nex.y] = 1;
su[nex.x][nex.y]++;
ps.push(nex);
}
}
}
}
int main()
{
while(cin >> n >> m){
ll ans = 0;
while(!ps.empty()) ps.pop();
memset(su,0,sizeof(su));
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
cin >> a[i][j];
}
}
memset(vis,0,sizeof(vis));
vis[1][1] = 1;su[1][1]++;
ps.push(node{1,1});
for(int i = 2;i <= n;i++){
vis[i][1] = 1;
su[i][1]++;
ps.push(node{i,1});
}
for(int i = 2;i <= m;i++){
vis[1][i] = 1;su[1][i]++;
ps.push(node{1,i});
}
bfs();
memset(vis,0,sizeof(vis));
su[n][m]++;vis[n][m] = 1;
ps.push(node{n,m});
for(int i = 1;i < n;i++){
vis[i][m] = 1;su[i][m]++;
ps.push(node{i,m});
}
for(int i = 1;i < m;i++){
vis[n][i] = 1;su[n][i]++;
ps.push(node{n,i});
}
bfs();
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(su[i][j] == 2) ans++;
}
}
cout << ans << endl;
}
return 0;
}
K: 吃鸡路线
迪杰斯特拉算法,实在找不到错,用别人的算法做了一遍
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10005;
int n;
ll all,tot;
ll head[maxn],dps[maxn];
unordered_map<string,ll> ID;
struct node{
int v,w,nex;
}edge[maxn<<1];
struct nodes{
ll x,y;
friend bool operator < (nodes x,nodes y)
{
return x.y > y.y;
}
};
void EdgeBuild(int u,int v,int w)
{
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nex = head[u];
head[u] = tot++;
}
int getID(string s)
{
if(ID.find(s) == ID.end()) ID[s] = all++;
return ID[s];
}
void init()
{
all = tot = 0;
memset(head,-1,sizeof(head));
ID.clear();
}
ll dist(string start,string fin)
{
priority_queue<nodes> Q;
Q.push(nodes{getID(start),0});
memset(dps,0x3f,sizeof(dps));
dps[ID[start]] = 0;
while(!Q.empty()){
auto cur = Q.top();Q.pop();
if(cur.x == getID(fin)) return cur.y;
for(int i = head[cur.x];i != -1;i = edge[i].nex){
if(cur.y + edge[i].w < dps[edge[i].v]){
dps[edge[i].v] = cur.y + edge[i].w;
Q.push(nodes{edge[i].v,dps[edge[i].v]});
}
}
}
return -1;
}
int main()
{
while(cin >> n && n != -1){
string st,en;
cin >> st >> en;
init();
for(int i = 0;i < n;i++){
string l,r;ll s;
cin >> l >> r >> s;
int ll = getID(l);int rr = getID(r);
EdgeBuild(ll,rr,s);
EdgeBuild(rr,ll,s);
}
cout << dist(st,en) << endl;
}
return 0;
}